我的朋友和我正在互相出谜题,我不知道该如何解决这个问题。 我的假设是可能需要使用一些位运算符,但我不确定。
我的朋友和我正在互相出谜题,我不知道该如何解决这个问题。 我的假设是可能需要使用一些位运算符,但我不确定。
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "2 + 3 = %d", add(2,3));
return 0;
}
XOR (x ^ y
) 是没有进位的加法。(x & y)
是每个比特位的进位。 (x & y) << 1
是每个比特位的进位。循环一直将进位与和相加,直到所有比特位的进位都为零。
int add(int a, int b) {
const char *c=0;
return &(&c[a])[b];
}
c
的地址为0。变量 c[a]
的地址为 0 + a = a
。而 (&c[a])[b]
的地址为 a + b
。虽然使用了巧妙的技巧,但仍然隐式地使用了 "add" 操作。 - Landys没有 + 对吗?
int add(int a, int b)
{
return -(-a) - (-b);
}
CMS的add()函数很优美。不应该被一元负号(非按位操作,相当于使用加法:-y == (~y)+1)所污染。因此,这里提供了一个使用相同的只使用位运算符的设计的减法函数:
int sub(int x, int y) {
unsigned a, b;
do {
a = ~x & y;
b = x ^ y;
x = b;
y = a << 1;
} while (a);
return b;
}
a - (-b)
很容易实现。因此,回答如何在不使用任何算术运算符的情况下进行操作更符合问题的本意。此外,User23126直接说明,即使它执行加法,“+”运算符以外的运算符也是不可接受的,“++”与否定背后的一部分非常相似。 - Deadcode定义“最佳”。以下是Python版本:
len(range(x)+range(y))
+
运算符执行的是列表连接,而不是加法运算。
#define BIT_LEN 32
#define ADD_OK 0
#define ADD_UNDERFLOW 1
#define ADD_OVERFLOW 2
int ripple_add(int a, int b, char carry_in, char* flags) {
int result = 0;
int current_bit_position = 0;
char a_bit = 0, b_bit = 0, result_bit = 0;
while ((a || b) && current_bit_position < BIT_LEN) {
a_bit = a & 1;
b_bit = b & 1;
result_bit = (a_bit ^ b_bit ^ carry_in);
result |= result_bit << current_bit_position++;
carry_in = (a_bit & b_bit) | (a_bit & carry_in) | (b_bit & carry_in);
a >>= 1;
b >>= 1;
}
if (current_bit_position < BIT_LEN) {
*flags = ADD_OK;
}
else if (a_bit & b_bit & ~result_bit) {
*flags = ADD_UNDERFLOW;
}
else if (~a_bit & ~b_bit & result_bit) {
*flags = ADD_OVERFLOW;
}
else {
*flags = ADD_OK;
}
return result;
}
基于Go语言的解决方案
func add(a int, b int) int {
for {
carry := (a & b) << 1
a = a ^ b
b = carry
if b == 0 {
break
}
}
return a
}
相同的解决方案可以用Python实现,但是在Python中有一些关于数字表示的问题,Python对于整数有超过32位的限制,因此我们需要使用掩码来获取最后32位。
例如:如果我们不使用掩码,我们将无法得到数字(-1,1)的结果。
def add(a,b):
mask = 0xffffffff
while b & mask:
carry = a & b
a = a ^ b
b = carry << 1
return (a & mask)
return a&mask
。检查是否需要复杂化代码只会让事情变得更麻烦,而且 &
运算是很便宜的。 - Peter Cordes使用位运算符的Java解决方案:
// Recursive solution
public static int addR(int x, int y) {
if (y == 0) return x;
int sum = x ^ y; //SUM of two integer is X XOR Y
int carry = (x & y) << 1; //CARRY of two integer is X AND Y
return addR(sum, carry);
}
//Iterative solution
public static int addI(int x, int y) {
while (y != 0) {
int carry = (x & y); //CARRY is AND of two bits
x = x ^ y; //SUM of two bits is X XOR Y
y = carry << 1; //shifts carry to 1 bit to calculate sum
}
return x;
}
public static
从两个中移除,它也可以在C中工作。+1 - MD XFxor
是一种无进位加法。递归版本中的第一个注释表明它是两个整数的和,这是错误的。 - Peter Cordesint add(int x, int y) {
return y == 0 ? x : add(x ^ y, (x & y) << 1);
}