Your goal is to add two input numbers without using any of the following math operators: +,-,*,/.

Additionally, you can't use any built-in functions that are designed to replace those math operators.


Smallest code (in number of bytes) wins.


Most of the programs i've seen either concatenate two arrays containing their numbers, or make first number of a character, append second number characters, then count them all.

Shortest array counter: APL with 8 chars, by Tobia

Shortest array concatenation: Golfscript with 4 chars, by Doorknob

Shortest logarithmic solution: TI-89 Basic with 19 chars, by Quincunx

Integration solution: Mathematica with 45 chars, by Michael Stern

Coolest, in my opinion: bitwise operators in javascript, by dave

  • \$\begingroup\$ Will it have floats? \$\endgroup\$ – Ismael Miguel Feb 16 '14 at 1:06
  • 7
    \$\begingroup\$ Will it have negative numbers? (Currently, all the answers assume that the numbers will be positive, so you probably shouldn't change that) \$\endgroup\$ – Doorknob Feb 16 '14 at 3:48
  • 4
    \$\begingroup\$ What about the mathematical solutions? You forgot to list those! This integrates, and this plays with logarithms \$\endgroup\$ – Justin Feb 17 '14 at 0:54
  • 3
    \$\begingroup\$ Why did you accept one of the longer solutions? Is it because it accepts negative numbers while the shortest solutions (this and this) don't? If so, my answer supports negative numbers (it also supports floating point) and is shorter than this one. You tagged this question as code-golf, thus you are obliged to accept the shortest solution. \$\endgroup\$ – Justin Feb 20 '14 at 21:01
  • 2
    \$\begingroup\$ Define "number". Any integer? Non-negative integers? Do they have to be base-10? \$\endgroup\$ – SuperJedi224 Jan 20 '17 at 13:44

77 Answers 77


Smalltalk, 21 13

All of the following only work on positive integers. See the other Smalltalk answer for a serious one.


shifting to a large integer and asking it for its high bit index (bad, ST indexing is 1-based, so I need an additional right shift):



similar, and even a bit shorter (due to Smalltalk precedence rules, and no right shift needed):

1<<a<<b log:2 


another variation of the "collection-concatenating-asking size" theme,
given two numbers a and b,

((Array new:a),(Array new:b)) size

using Intervals as collection, we get a more memory friendly version ;-) in 21 chars:


not recommended for heavy number crunching, though.


For your amusement, if you want to trade time for memory, try:

Time secondsToRun:[
   Delay waitForSeconds:a.
   Delay waitForSeconds:b.

which is usually accurate enough (but no guarantee ;-)))


write to a file and ask it for its size

        't' asFilename 
            writingFileDo:[:s |
                a timesRepeat:[ 'x' printOn:s ].
                b timesRepeat:[ 'x' printOn:s ]];
    ] ensure:[
        't' asFilename delete
) print

Javascript (25)


This adds two variables x and y, using only bitwise operations, and stores the result in x.

This works with negative numbers, too.

  • 1
    \$\begingroup\$ @dave, if you're switching to a while, you can save two more chars with while(y)x^=y,y=(y&x^y)<<1! \$\endgroup\$ – Dom Hastings Feb 16 '14 at 16:08
  • 1
    \$\begingroup\$ More readable version of the code: Add two numbers without using arithmetic operators. \$\endgroup\$ – Franck Dernoncourt Feb 16 '14 at 16:49
  • 3
    \$\begingroup\$ @user3125280, The problem isn't "do addition without doing addition" (which is a bit nonsensical), but rather "do addition without basic math operators" \$\endgroup\$ – Brian S Feb 17 '14 at 16:18
  • 8
    \$\begingroup\$ @user3125280, I'm sorry, but any rudeness you interpreted from my comment was not intended. I do think you'll have a hard time finding very many people who agree that XOR should be grouped with PLUS in the category of "basic arithmetic," though. Even beyond finding people who agree, the OP explicitly calls out what operators are not permitted, and XOR is not one of them. Ergo, this is a valid answer. \$\endgroup\$ – Brian S Feb 17 '14 at 19:33
  • 3
    \$\begingroup\$ for(;y;y=(y&x^y)<<1)x^=y is 1 byte shorter :) \$\endgroup\$ – William Barbosa Oct 15 '14 at 18:10

C - 38 bytes

main(){return printf("%*c%*c",3,0,4);}

I do cheat a bit here, the OP said to not use any math operators.

The * in the printf() format means that the field width used to print the character is taken from an argument of printf(), in this case, 3 and 4. The return value of printf() is the number of characters printed. So it's printing one ' ' with a field-width of 3, and one with a field-width of 4, makes 3 + 4 characters in total.

The return value is the added numbers in the printf() call.

  • 3
    \$\begingroup\$ You should make 3 and 4 parameters, and the function doesn't need to be main. Also, if you don't care what you print, you can replace one ' ' with 0 and omit the second. \$\endgroup\$ – ugoren Feb 16 '14 at 8:06

Python - 49 bytes

Assuming input by placement in variables x and y.

from math import*
print log(log((e**e**x)**e**y))

This 61 byte solution is a full program:

from math import*
print log(log((e**e**input())**e**input()))

Considering that you did not ban exponentiation, I had to post this. When you simplify the expression using properties of logarithms, you simply get print input() + input().

This supports both negative and floating point numbers.

Note: I followed gnibbler's advice and split this answer into three. This is the Mathematica solution, and this is the TI-89 Basic solution.

  • \$\begingroup\$ I was trying to do something similar to that with javascript, but forgot what was the formula since it was some years from last time I saw it and was searching the internet to find it. \$\endgroup\$ – Victor Stafusa Feb 16 '14 at 7:30
  • 4
    \$\begingroup\$ @Victor I created the formula on my own. I remember math very clearly. \$\endgroup\$ – Justin Feb 16 '14 at 7:31
  • 1
    \$\begingroup\$ Your Mathematica is very close, you just need to capitalize the built-in symbols. Log[Log[(E^E^x)^(E^y)]] works (23 characters, or 22 if you use @ notation for the outer function wrapping). \$\endgroup\$ – Michael Stern Feb 16 '14 at 12:23
  • \$\begingroup\$ "If I am allowed to assume input by placement in variables x and y.." I think you can - others do so as well. \$\endgroup\$ – blabla999 Feb 16 '14 at 17:38
  • \$\begingroup\$ @MichaelStern: You can save two more characters by skipping the parentheses around E^y. Using Log[Log[(E^E^x)^E^y]] seems to work fine. \$\endgroup\$ – alexwlchan Feb 16 '14 at 17:54

JavaScript [25 bytes]

  • 1
    \$\begingroup\$ Your answer looks bad (and downvote-attracting), but it is actually a nice answer. Please delete this one to get rid of the downvotes and repost this with some text explaining it. I will upvote your new answer. \$\endgroup\$ – Victor Stafusa Feb 18 '14 at 17:36
  • 1
    \$\begingroup\$ Now it looks really good, I like it. Certainly is worth more upvotes. \$\endgroup\$ – VisioN Feb 19 '14 at 15:45

Mathematica, 21 bytes

There are a number of ways to do this in Mathematica. One, use the Accumulate function and toss everything but the final number in the output. As with my other solution below, I assume the input numbers are in the variables a and b. 21 bytes.

Last@Accumulate@{a, b}

More fun, though it is 45 characters, use the numbers to define a line and integrate under it.

Integrate[Fit[{{0, a}, {2, b}}, {x, 1}, x], {x, 0, 2}]

As a bonus, both solutions work for all complex numbers, not just positive integers as seems to be the case for some other solutions here.

  • 2
    \$\begingroup\$ I love the integration! (although, strictly speaking this adds up something). +1 \$\endgroup\$ – blabla999 Feb 16 '14 at 3:54
  • \$\begingroup\$ The 1st solution is invalid. Quoting the author of the challenge: "Additionally, you can't use any built-in functions that are designed to replace those math operators.". I had given this solution: function _(){return array_sum(func_get_args());}. I had to take it down 'cause I couldn't find a short way to "fix" it. \$\endgroup\$ – Ismael Miguel Feb 16 '14 at 22:25
  • \$\begingroup\$ @Ismael Miguel Accumulate[] is not designed to replace Plus. It happens to give the sum of a list of numbers among its outputs, and I take advantage of that. \$\endgroup\$ – Michael Stern Feb 16 '14 at 22:28
  • \$\begingroup\$ But it does make the sum of all the elements in that list, right? If it does, in my opinion, it's as invalid as using array_sum() in php, which does the same exact thing. \$\endgroup\$ – Ismael Miguel Feb 16 '14 at 22:37
  • 3
    \$\begingroup\$ @Ismael Miguel There exists a Mathematica function that sums an array, called Total[]. I agree it would be against the rules as specified to use that function, but I did not do so. The output of Accumulate[{a,b}] is not a+b. \$\endgroup\$ – Michael Stern Feb 16 '14 at 23:52

GolfScript, 6 4 characters/bytes

Input in the form of 10, 5 (=> 15).


The + is array concatenation, not addition.

How it works is that , is used to create an array of the length that the number is (0,1,...,n-2,n-1). This is done for both numbers, then the arrays are concatenated. , is used again for a different purpose, to find the length of the resulting array.

Now, here's the trick. I really like this one because it abuses the input format. It looks like it's just inputting an array, but really, since the input is being executed as GolfScript code, the first , is already done for me! (The old 6-character version was ~,\,+, with input format 10 5, which I shaved 2 chars off by eliminating the \, (swap-array)).

Old version (12):

Creates a function f.


The * and + are string repetition and concatenation respectively, not arithmetic functions.

Explanation: n creates a one-character string (a newline). This is then repeated a times, then the same thing is done with b. The strings are concatenated, and then , is used for string length.

  • \$\begingroup\$ Does it work for negative numbers too? \$\endgroup\$ – Michael Stern Feb 16 '14 at 3:47
  • \$\begingroup\$ @MichaelStern No, but that was never mentioned in the question. Hmm, I've added a comment. Most (in fact, all) of the other answers also assume positives. \$\endgroup\$ – Doorknob Feb 16 '14 at 3:47
  • \$\begingroup\$ See my Mathematica solution. In the right language, solutions for negative numbers are possible. \$\endgroup\$ – Michael Stern Feb 16 '14 at 3:53
  • \$\begingroup\$ @MichaelStern LOL @ "right language" on this site of all places… \$\endgroup\$ – Tobia Feb 16 '14 at 23:05

C, 29 27 Bytes

Using pointer arithmetic:


x is defined as a pointer, but the caller should pass an integer.

An anonymous user suggested the following - also 27 bytes, but parameters are integers:

  • \$\begingroup\$ The first form probably breaks badly if passing two ints on the now-common systems where int has 32 bits, and pointers have 64 bits. The second avoids that problem. \$\endgroup\$ – hvd Feb 17 '14 at 12:24
  • \$\begingroup\$ @hvd, Both work, at least on Linux 64bit. Integer parameters are extended to machine register size anyway. \$\endgroup\$ – ugoren Feb 17 '14 at 12:29
  • \$\begingroup\$ Ah, fair enough, agreed that that'll likely be the common case. Will comment again if I can find a concrete example that doesn't work, though. :) \$\endgroup\$ – hvd Feb 17 '14 at 12:32

Brainf*ck, 9 36



This works without using simple addition; it goes through and lays a trail of 1's and then counts them up

Note: The + and - are merely single increments and nothing can be done in brainf*ck without them. They aren't really addition/subtraction so I believe this still counts.

  • \$\begingroup\$ -1. This is simple addition. If you did something that is not addition, multiplication, etc, then it counts, but as is, this does not count. \$\endgroup\$ – Justin Feb 16 '14 at 5:15
  • \$\begingroup\$ @Quincunx I fixed it; i did it by goign through and leaving a trail of ones and then sweeping through and 'picking up' that trail \$\endgroup\$ – ASKASK Feb 16 '14 at 5:42
  • 3
    \$\begingroup\$ Reversed. Nice job. \$\endgroup\$ – Justin Feb 16 '14 at 5:43

J (6)

You didn't say we couldn't use the succ function:




It just does 9 repetitions of >: on 8.

The list concatenation approach works, too: #@,&(#&0). And - I know it's against the rules - I can't let this answer go without the most J-ish solution: *&.^ (multiplication under exponentiation).


Postscript, 41

We define function with expression 41 bytes long as:

/a{0 moveto 0 rmoveto currentpoint pop}def

Then we call it e.g. as:

gs -q -dBATCH -c '/a{0 moveto 0 rmoveto currentpoint pop}def' -c '10 15 a ='

Which gives


It easily handles negatives and floats, unlike most competitors:-)


bash, 20 chars

(seq 10;seq 4)|wc -l

Smalltalk (now seriously), 123 118 105(*)

Sorry for answering twice, but consider this a serious answer, while the other one was more like humor. The following is actually executed right at this very moment in all of our machines (in hardware, though). Strange that it came to no one else's mind...

By combining two half-adders, and doing all bits of the words in parallel, we get (inputs a,b; output in s) readable version:

  s := a bitXor: b.            
  c := (a & b)<<1.             

  [c ~= 0] whileTrue:[        
     cn := s & c.
     s := s bitXor: c.
     c := cn<<1.
     c := c & 16rFFFFFFFF.
     s := s & 16rFFFFFFFF.

The loop is for carry propagation. The masks ensure that signed integers are handled (without them, only unsigned numbers are possibe). They also define the word length, the above being for 32bit operation. If you prefer 68bit addition, change to 16rFFFFFFFFFFFFFFFFF.

golf version (123 chars) (avoids the long mask by reusing in m):

[:a :b||s c n m|s:=a bitXor:b.c:=(a&b)<<1.[c~=0]whileTrue:[n:=s&c.s:=s bitXor:c.c:=n<<1.c:=c&m:=16rFFFFFFFF.s:=s&m].s]

(*) By using -1 instead of 16rFFFFFFFF, we can golf better, but the code no longer works for arbitrary precision numbers, only for machine-word sized smallIntegers (the representation for largeIntegers is not defined in the Ansi standard):

[:a :b||s c n|s:=a bitXor:b.c:=(a&b)<<1.[c~=0]whileTrue:[n:=s&c.s:=s bitXor:c.c:=n<<1.c:=c&-1.s:=s&-1].s]

this brings the code size down to 105 chars.

  • \$\begingroup\$ This is code-golf, so golf your answer. \$\endgroup\$ – Victor Stafusa Feb 16 '14 at 9:55
  • 1
    \$\begingroup\$ no chance to win, but I'll do it for you ;-) \$\endgroup\$ – blabla999 Feb 16 '14 at 15:09
  • \$\begingroup\$ Nice to see a Smalltalk answer! \$\endgroup\$ – Toothbrush Feb 16 '14 at 18:25

APL, 8 and 12

Nothing new here, the array counting version:


and the log ○ log version:


I just thought they looked cool in APL!

{≢     }       count
  ∊            all the elements in
   ⍳¨          the (two) sequences of naturals from 1 up to
     ⍺⍵        both arguments


{⍟⍟        }   the double logarithm of
   (**⍺)       the double exponential of ⍺
        *      raised to
         *⍵    the exponential of ⍵
  • 2
    \$\begingroup\$ To be fair, everything looks cool in APL. \$\endgroup\$ – Michael Stern Feb 19 '14 at 21:09
  • \$\begingroup\$ You could make the first one a tacit prefix function for 5: ≢∘∊⍳¨ \$\endgroup\$ – Adám Jul 25 at 10:38
  • \$\begingroup\$ @Adám Yes, but I don't like tacit functions and I find them difficult to read. \$\endgroup\$ – Tobia Jul 27 at 10:35
  • \$\begingroup\$ @Tobia Maybe you don't like them because you find them difficult to read? I'm running a workshop on that… Have you seen my lesson on it? \$\endgroup\$ – Adám Jul 27 at 21:58
  • \$\begingroup\$ @Adám cool, thank you! Will check it out. \$\endgroup\$ – Tobia Aug 8 at 16:29

sed, 359 bytes (without the fancy formatting)

Sorry for the late answer, and probably the longest answer here by far. But I wanted to see if this is possible with sed:

                       s/([^ ]+) ([^ ]+)/\1:0::\2:/
                       :d /^([^:]+):\1::([^:]+):/tx
                       s/:(_+:)/:1\1/g; y/_/0/; # #
                       bd;  :x  s/.*::([^:]+):/\1/;

This is similar to https://codegolf.stackexchange.com/a/38087/11259, which simply increments numbers in a string. But instead it does the increment operations in a loop.

Input is taken from STDIN in the form "x y". That is first transformed to "x:0::y:". Then we increment all numbers that come after ":" characters, until we get "x:x::(x+y):". Then we finally return (x+y).


$ printf "%s\n" "0 0" "0 1" "1 0" "9 999" "999 9" "12345 67890" "123 1000000000000000000000"  | sed -rf add.sed

Note that this only works for the natural numbers. However (in theory at least) it works for arbitrarily large integers. Because we are doing x increment operations on y, ordering can make a big difference to speed: x < y will be faster than x > y.


Dash, 18 bytes

time -f%e sleep $@

Requires GNU time 1.7 or higher. Output is to STDERR.

Try it online!

Note that this will not work in B​ash, since its builtin time command differs from GNU time.

At the cost of one additional byte, \time can be used instead of time to force Bash to use the external command.

  • \$\begingroup\$ what happens if one of the inputs is negative? \$\endgroup\$ – Michael Stern Feb 16 '14 at 3:46
  • 4
    \$\begingroup\$ It fails. Just like all the other answers. \$\endgroup\$ – Dennis Feb 16 '14 at 3:47
  • 5
    \$\begingroup\$ Drats! I hoped it gave the result before the question was asked. \$\endgroup\$ – Tobia Feb 16 '14 at 23:08
  • 3
    \$\begingroup\$ Yeah. I also was in high hopes that by inserting random sleep -3 I could speed up my programs. What a let-down. \$\endgroup\$ – Alfe Feb 17 '14 at 10:24
  • 1
    \$\begingroup\$ @userunknown \time should work as well in Bash. \$\endgroup\$ – Dennis Mar 25 '18 at 1:41

Javascript (67)

There is probably much better

  • \$\begingroup\$ You shouldn't give a definitive answer without knowing if it needs floats or not. And it wont handle NaN's. But its quite a nice code! \$\endgroup\$ – Ismael Miguel Feb 16 '14 at 1:17
  • \$\begingroup\$ I think all the joins are unnecessary. The Array constructor makes an array of undefineds, which can be counted: a=Array;p=parseInt;r=prompt;alert(a(p(r())).concat(a(p(r()))).length) \$\endgroup\$ – Ben Reich Feb 16 '14 at 1:30
  • \$\begingroup\$ @BenReich, you're right, thanks \$\endgroup\$ – Michael M. Feb 16 '14 at 1:31
  • \$\begingroup\$ @Michael Also, the Number constructor saves 2 characters over parseInt \$\endgroup\$ – Ben Reich Feb 16 '14 at 1:35
  • \$\begingroup\$ @Michael Also, if you remove the alert, the output would still go to the console, but that makes the answer a little bit less fun. You could also reuse the prompt variable instead of alert, (the constructor alerts the argument with the prompt). Anyway, nice answer! \$\endgroup\$ – Ben Reich Feb 16 '14 at 1:39

Ruby, 18 chars


And two more verbose variants, 29 chars


Another version, 32 chars


C# - on the fly code generation

Yeah, there is actually an addition in there, but not the + operator and not even a framework function which does adding, instead we generate a method on the fly that does the adding.

public static int Add(int i1, int i2)
    var dm = new DynamicMethod("add", typeof(int), new[] { typeof(int), typeof(int) });
    var ilg = dm.GetILGenerator();
    var del = (Func<int, int, int>)dm.CreateDelegate(typeof(Func<int, int, int>));
    return del(i1, i2);

Ruby 39


R 36


where rep builds a vector of x ones followed by y twos.

  • 2
    \$\begingroup\$ You can make a program that does the same a bit shorter: length(rep(1:2,scan())) \$\endgroup\$ – Masclins May 6 '16 at 9:59

TI Basic 89 - 19 bytes

Run this in your TI-89 (Home screen or programming app):


This uses log rules to compute x+y, just like in this solution. As a bonus, it works for decimal and integer numbers. It works for all real numbers. If the logarithm rules are still valid with complex exponents, then this works for complex numbers too. However, my calculator spits out junk when I try to insert complex exponents.

  • 3
    \$\begingroup\$ Isn't ln 1 byte in TI Basic? Also, you can drop the closing parentheses, bringing this down to 15 bytes. \$\endgroup\$ – ɐɔıʇǝɥʇuʎs May 6 '14 at 9:22

Thanks to Michael Stern for teaching me Mathematica notation.

Mathematica - 21 20 bytes


This uses the same approach as this solution, but it is in Mathematica to make it shorter. This works for negative and floating point numbers as well as integers in x and y.

Simplifying the expression using log rules yields x+y, but this is valid since it uses exponentiation, not one of the 4 basic operators.

  • \$\begingroup\$ Are you sure it works for complex numbers? \$\endgroup\$ – Michael Stern Feb 20 '14 at 2:42

C# - string arithmetics

We convert both numbers to strings, do the addition with string cutting (with carry and everything, you know), then parse back to integer. Tested with i1, i2 in 0..200, works like a charm. Find an addition in this one!

public static int Add(int i1, int i2)
    var s1 = new string(i1.ToString().Reverse().ToArray());
    var s2 = new string(i2.ToString().Reverse().ToArray());
    var nums = "01234567890123456789";
    var c = '0';
    var ret = new StringBuilder();
    while (s1.Length > 0 || s2.Length > 0 || c != '0')
        var c1 = s1.Length > 0 ? s1[0] : '0';
        var c2 = s2.Length > 0 ? s2[0] : '0';
        var s = nums;
        s = s.Substring(int.Parse(c1.ToString()));
        s = s.Substring(int.Parse(c2.ToString()));
        s = s.Substring(int.Parse(c.ToString()));
        if (s1.Length > 0)
            s1 = s1.Substring(1);
        if (s2.Length > 0)
            s2 = s2.Substring(1);
        c = s.Length <= 10 ? '1' : '0';
    return int.Parse(new string(ret.ToString().ToCharArray().Reverse().ToArray()));

C (79)

void main(){int a,b;scanf("%d%d",&a,&b);printf("%d",printf("%*c%*c",a,0,b,0));}

Python -- 22 characters

  • 1
    \$\begingroup\$ I think that counts as addition? \$\endgroup\$ – TheDoctor Feb 17 '14 at 2:32
  • 1
    \$\begingroup\$ it's concatenation \$\endgroup\$ – pydud Feb 17 '14 at 2:32

APL: 2


This converts the numbers from base 1, so (n*1^1)+(m*1^2) which is exactly n+m.

Can be tried on TryApl.org



Adds X and Y

  • 1
    \$\begingroup\$ You sure know how to copy solutions: codegolf.stackexchange.com/a/21033/9498 \$\endgroup\$ – Justin Feb 19 '14 at 9:39
  • \$\begingroup\$ First, this doesn't work because it uses log( instead of ln(. Second, it is actually ten bytes if written in the form ln(ln(e^(e^(X))^e^(Y. \$\endgroup\$ – lirtosiast May 16 '15 at 19:40

K, 2 bytes


Usage example:

  #&7 212

Apply the "where" operator (monadic &) to the numbers in an input list (possibly taking liberty with the input format). This will produce a list containing the first number of zeroes followed by the second number of ones:

  &3 2
0 0 0 1 1

Normally this operator is used as a "gather" to produce a list of the indices of the nonzero elements of a boolean list, but the generalized form comes in handy occasionally.

Then simply take the count of that list (monadic #).

If my interpretation of the input requirements is unacceptable, the following slightly longer solution does the same trick:


Pyth, 29 bytes


Try it online!

My first submission here!

This compiles to:

assign('Q',eval_input())     # Q
assign('[G,H]',Q)            #A
while Pnot(equal(G,0)):      #  W!qG0
  assign('k',bitand(G,H))    #       =k.&GH
  assign('H',index(G,H))     #             =HxGH  (index in this case is XOR)
  assign('k',leftshift(k,1)) #                  =k.<k1
  assign('G',k)              #                        =Gk)
imp_print(H)                 #                            H
  • 1
    \$\begingroup\$ Welcome to the site! \$\endgroup\$ – Wheat Wizard Feb 7 '18 at 15:14

Your Answer

