如何在不使用++或+或任何其他算术运算符的情况下将两个数字相加?
这是很久以前在一些校园采访中问的一个问题。无论如何,今天有人问了一些有关位操作的问题,并在回答中提到了一个美丽的 斯坦福钻头 。我花了一些时间研究它,并认为实际上可能是该问题的答案。我不知道,我找不到。是否存在答案?
这是我前一段时间写的好玩的东西。它使用二进制补码表示,并通过使用带进位的重复移位来实现加法,主要在加法方面实现其他运算符。
#include <stdlib.h> /* atoi() */ #include <stdio.h> /* (f)printf */ #include <assert.h> /* assert() */ int add(int x, int y) { int carry = 0; int result = 0; int i; for(i = 0; i < 32; ++i) { int a = (x >> i) & 1; int b = (y >> i) & 1; result |= ((a ^ b) ^ carry) << i; carry = (a & b) | (b & carry) | (carry & a); } return result; } int negate(int x) { return add(~x, 1); } int subtract(int x, int y) { return add(x, negate(y)); } int is_even(int n) { return !(n & 1); } int divide_by_two(int n) { return n >> 1; } int multiply_by_two(int n) { return n << 1; } int multiply(int x, int y) { int result = 0; if(x < 0 && y < 0) { return multiply(negate(x), negate(y)); } if(x >= 0 && y < 0) { return multiply(y, x); } while(y > 0) { if(is_even(y)) { x = multiply_by_two(x); y = divide_by_two(y); } else { result = add(result, x); y = add(y, -1); } } return result; } int main(int argc, char **argv) { int from = -100, to = 100; int i, j; for(i = from; i <= to; ++i) { assert(0 - i == negate(i)); assert(((i % 2) == 0) == is_even(i)); assert(i * 2 == multiply_by_two(i)); if(is_even(i)) { assert(i / 2 == divide_by_two(i)); } } for(i = from; i <= to; ++i) { for(j = from; j <= to; ++j) { assert(i + j == add(i, j)); assert(i - j == subtract(i, j)); assert(i * j == multiply(i, j)); } } return 0; }