# Add without addition (or any of the 4 basic arithmetic operators)

Problem:

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.

Scoring:

Smallest code (in number of bytes) wins.

Update

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

• Will it have floats? Feb 16, 2014 at 1:06
• Will it have negative numbers? (Currently, all the answers assume that the numbers will be positive, so you probably shouldn't change that) Feb 16, 2014 at 3:48
• What about the mathematical solutions? You forgot to list those! This integrates, and this plays with logarithms Feb 17, 2014 at 0:54
• 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. Feb 20, 2014 at 21:01
• Define "number". Any integer? Non-negative integers? Do they have to be base-10? Jan 20, 2017 at 13:44

## Javascript (25)

while(y)x^=y,y=(y&x^y)<<1


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

This works with negative numbers, too.

• @dave, if you're switching to a while, you can save two more chars with while(y)x^=y,y=(y&x^y)<<1! Feb 16, 2014 at 16:08
• More readable version of the code: Add two numbers without using arithmetic operators. Feb 16, 2014 at 16:49
• @user3125280, The problem isn't "do addition without doing addition" (which is a bit nonsensical), but rather "do addition without basic math operators" Feb 17, 2014 at 16:18
• @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. Feb 17, 2014 at 19:33
• for(;y;y=(y&x^y)<<1)x^=y is 1 byte shorter :) Oct 15, 2014 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.

• 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. Feb 16, 2014 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.

• 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. Feb 16, 2014 at 7:30
• @Victor I created the formula on my own. I remember math very clearly. Feb 16, 2014 at 7:31
• 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). Feb 16, 2014 at 12:23
• "If I am allowed to assume input by placement in variables x and y.." I think you can - others do so as well. Feb 16, 2014 at 17:38
• @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. Feb 16, 2014 at 17:54

## JavaScript [25 bytes]

~eval([1,~x,~y].join(''))

• Now it looks really good, I like it. Certainly is worth more upvotes. Feb 19, 2014 at 15:45

# 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.

{n*\n*+,}: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.

• Does it work for negative numbers too? Feb 16, 2014 at 3:47
• @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. Feb 16, 2014 at 3:47
• See my Mathematica solution. In the right language, solutions for negative numbers are possible. Feb 16, 2014 at 3:53
• @MichaelStern LOL @ "right language" on this site of all places… Feb 16, 2014 at 23:05

## 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.

• I love the integration! (although, strictly speaking this adds up something). +1 Feb 16, 2014 at 3:54
• 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. Feb 16, 2014 at 22:25
• @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. Feb 16, 2014 at 22:28
• 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. Feb 16, 2014 at 22:37
• @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. Feb 16, 2014 at 23:52

## C, 29 27 Bytes

Using pointer arithmetic:

f(x,y)char*x;{return&x[y];}


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:

f(x,y){return&x[(char*)y];}

• 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.
– hvd
Feb 17, 2014 at 12:24
• @hvd, Both work, at least on Linux 64bit. Integer parameters are extended to machine register size anyway. Feb 17, 2014 at 12:29
• 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. :)
– hvd
Feb 17, 2014 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.

• -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. Feb 16, 2014 at 5:15
• @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 Feb 16, 2014 at 5:42
• Reversed. Nice job. Feb 16, 2014 at 5:43

## 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

25.0


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

# J (6)

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

>:@[&0


Usage:

   9>:@[&0(8)
17


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).

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.
].
s


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.

• This is code-golf, so golf your answer. Feb 16, 2014 at 9:55
• no chance to win, but I'll do it for you ;-) Feb 16, 2014 at 15:09
• Nice to see a Smalltalk answer! Feb 16, 2014 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 ⍵

• To be fair, everything looks cool in APL. Feb 19, 2014 at 21:09
• You could make the first one a tacit prefix function for 5: ≢∘∊⍳¨
Jul 25, 2019 at 10:38
• @Adám Yes, but I don't like tacit functions and I find them difficult to read. Jul 27, 2019 at 10:35
• @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?
Jul 27, 2019 at 21:58
• @Adám Did check it out. My main gripe remains: trains are not legible. With traditional style, you can understand an expression incrementally as you read it, both left to right: ≢∊⍳... means "number of elements in the sequences..." and right to left: ...⍳¨⍺⍵ means "first generate sequences from ⎕IO to ⍺ and ⍵, then..." But with trains, you cannot begin to understand the expr until you have finished understanding every symbol in it and created the entire syntax tree in your mind, because a single mistake in the rightmost corner could (and does) shift the meaning for the entire train Aug 10, 2019 at 11:23

# 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/(:[^:]*)9([_:])/\1_\2/g;td
s/(:[^:]*)8(_*:)/\19\2/g;s/(:[^:]*)7(_*:)/\18\2/g;s/(:[^:]*)6(_*:)/\17\2/g
s/(:[^:]*)5(_*:)/\16\2/g;s/(:[^:]*)4(_*:)/\15\2/g;s/(:[^:]*)3(_*:)/\14\2/g
s/(:[^:]*)2(_*:)/\13\2/g;s/(:[^:]*)1(_*:)/\12\2/g;s/(:[^:]*)0(_*:)/\11\2/g
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).

# Output

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


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.

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

# Smalltalk, 21 13

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

### version1

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):

(((1<<a)<<b)>>1)highBit


### version2

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

1<<a<<b log:2


### version3

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:

((1to:a),(1to:b))size


not recommended for heavy number crunching, though.

### version4

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 ;-)))

### version5

write to a file and ask it for its size

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


## Javascript (67)

There is probably much better

a=Array;p=Number;r=prompt;alert(a(p(r())).concat(a(p(r()))).length)

• 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! Feb 16, 2014 at 1:17
• 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) Feb 16, 2014 at 1:30
• @BenReich, you're right, thanks Feb 16, 2014 at 1:31
• @Michael Also, the Number constructor saves 2 characters over parseInt Feb 16, 2014 at 1:35
• @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! Feb 16, 2014 at 1:39

Ruby, 18 chars

a.times{b=b.next}


And two more verbose variants, 29 chars

[*1..a].concat([*1..b]).size


Another version, 32 chars

(''.rjust(a)<<''.rjust(b)).size


# 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();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Ret);
var del = (Func<int, int, int>)dm.CreateDelegate(typeof(Func<int, int, int>));
return del(i1, i2);
}


# Ruby 39

f=->a,b{[*1..a].concat([*1..b]).length}


## R 36

function(x,y)length(rep(1:2,c(x,y)))


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

• You can make a program that does the same a bit shorter: length(rep(1:2,scan())) May 6, 2016 at 9:59

# TI Basic 89 - 19 bytes

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

ln(ln((e^e^x)^e^y))


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.

• Isn't ln 1 byte in TI Basic? Also, you can drop the closing parentheses, bringing this down to 15 bytes. May 6, 2014 at 9:22

# Mathematica - 21 20 bytes

Log@Log[(E^E^x)^E^y]


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.

• Are you sure it works for complex numbers? Feb 20, 2014 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';
var c2 = s2.Length > 0 ? s2 : '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()));
ret.Append(s);
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

len(range(x)+range(y))

• I think that counts as addition? Feb 17, 2014 at 2:32
• it's concatenation Feb 17, 2014 at 2:32

APL: 2

1⊥


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

## TI-BASIC, 10

Adds X and Y

ln(ln(e^(e^(X))^e^(Y

• You sure know how to copy solutions: codegolf.stackexchange.com/a/21033/9498 Feb 19, 2014 at 9:39
• 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. May 16, 2015 at 19:40

# K, 2 bytes

#&


Usage example:

  #&7 212
219


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:

{#&x,y}


# Pyth, 29 bytes

AQW!qG0=k.&GH=HxGH=k.<k1=Gk)H


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

• Welcome to the site! Feb 7, 2018 at 15:14