Google Interview Question
Country: United States
Interview Type: In-Person
Good, but honestly I'd give you points off for the variable names you've chosen. Why not just call it "sum" and "carry" or something?
The way I've seen this asked isn't like it was asked here. Implement addition of unsigned integers without any arithmetic operators.
They are unsigned integers. So, as far as I can tell, there is no way to represent negative numbers.
For signed integers, the first bit tells whether the number is positive or negative. For unsigned, the first bit is part of the number and hence, only positive numbers are allowed.
So, -b can't be represented using unsigned numbers.
Proof is shown for an unsigned byte (0xFF = 255). However the math works out the same for all unsigned types.
x + y = 255 + (-255 + x + y)
x + y = 255 - (255 - x - y)
x + y = 255 - ((255 - x) - y)
x + y = 255 - ((~x) - y)
x + y = ~((~x) - y)
To implement for an unsigned int:
unsigned int Add(unsigned int x, unsigned int y)
{
return ~((~x) - y);
}
#include<iostream>
using namespace std;
bool carry(bool ci, bool a, bool b)
{
bool car = (~ci & a & b) | (ci & ~a & b) | (ci & a & ~b) | (ci & a & b);
return car;
}
bool sum(bool ci, bool a, bool b)
{
bool s = (~ci & ~a & b) | (~ci & a & ~b) | (ci & ~a & ~b) | (ci & a & b);
return s;
}
void add(int a, int b)
{
int a1 = 1, b1 = 1,ci = 0, output = 0, totalsum = 0;
bool c2 = 0;
for(int i =0; i < 8; i++)
{
bool a0 = a & a1;
bool b0 = b & a1;
c2 = carry(ci, a0, b0);
int s= sum(ci, a0, b0);
s = s<<(i);
totalsum = totalsum | s;
ci = c2;
a1 = a1<<1;
}
cout<<totalsum<<endl;
}
int main()
{
add(13,35);
return 0;
}
// implement 1
unsigned Add(unsigned a, unsigned b) {
if(!a)return b;
if(!b)return a;
return Add(a^b,(a&b)<<1);
}
//implement 2
unsigned Add(unsigned a, unsigned b, unsigned carry) {
if(!(a|b))return carry; //both a and b is zero.
if(!((a|b)&1)) return Add(a>>1,b>>1,0)<<1|carry; // the lowest bit of a and b is 0
if(!(a&b&1)) return Add(a>>1,b>>1,carry)<<1|(!carry); //the lowest bit of a and b must be 1 one and 1 zero
return Add(a>>1,b>>1,1)<<1|carry;// both 1
}
A solution is to consider the add operation in two passes:
* first add bits set only in one of the number (logical or, and reverse bits set by logical and)
* remaining case is when the two bits are set to 1 (spotted by the logical and), and in such case we have to add the carry, that is, the bit position shifted - multiple carries may be present, and we need to loop until no carry is still there
Iterative version:
unsigned int sum(unsigned int a, unsigned int b) {
for(;;) {
const unsigned int x = a & b;
a |= b;
if (x == 0)
break;
a ^= x;
b = x << 1;
}
return a;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
long long x = atoi(argv[1]);
long long y = atoi(argv[2]);
long long S=0;
if(x==0 || y == 0) {
printf("%lld * %lld = %lld\n", x, y, S);
return 0;
}
long long t = x;
while(t){
S += y;
t--;
}
printf("%lld * %lld = %lld\n", x, y, S);
return S;
}
Like the way I learnt adding numbers when I'm a kid. Additionally, no math operator is used
- code_monkey October 17, 2012