Java 添加两个数字而不使用+;或任何算术运算符
这是我得到的参考实现,混淆的是,我认为不需要递归。我将代码和我的想法都发布在这里,任何见解都将不胜感激。如果我错了,请随时纠正我 顺便说一句,关于两种实施方式的差异,请参阅第5行。谢谢 问题是,是否需要递归?谢谢 参考实施Java 添加两个数字而不使用+;或任何算术运算符,java,algorithm,Java,Algorithm,这是我得到的参考实现,混淆的是,我认为不需要递归。我将代码和我的想法都发布在这里,任何见解都将不胜感激。如果我错了,请随时纠正我 顺便说一句,关于两种实施方式的差异,请参阅第5行。谢谢 问题是,是否需要递归?谢谢 参考实施 1 int add_no_arithm(int a, int b) { 2 if (b == 0) return a; 3 int sum = a ^ b; // add without carrying 4 int carry = (a & b) <<
1 int add_no_arithm(int a, int b) {
2 if (b == 0) return a;
3 int sum = a ^ b; // add without carrying
4 int carry = (a & b) << 1; // carry, but don’t add
5 return add_no_arithm(sum, carry); // recurse
6 }
1整数加法运算(整数a,整数b){
2如果(b==0)返回a;
3 int sum=a^b;//不带进位的加法
4整数进位=(a和b)位异或运算符^
仅在和中没有二进制进位时与加法运算符+
等效。如果有二进制进位,则它们不等效。例如,8+7
等于8^7
等于15
,但8+8
是16
而8^8>
为0
即使您已经正确计算了无进位和无进位和的和,如果这两个数字相加后会产生二进制进位呢?那么最后的^
运算符将是不正确的。如果没有+
运算符,我看到的唯一选项是递归,添加这些数字。这将重复出现,直到其中一个num贝尔斯是0
例如:
add(no_arithm(18, 6))
sum=a^b
18^6是20
carry=(a&b)第二种方法不适用于1+3
以下是步骤
a == 01
b == 11
sum = a^b == 10
carry = (a&b) << 1 == 10
sum ^ carry == 00 // wrong answer! 1 + 3 == 4
a==01
b==11
总和=a^b==10
进位=(a&b)
问题是,是否需要递归
是的,它是。你可以通过试验其他数字来看到这一点,而不仅仅是8+8。例如,尝试21和15,不使用递归,这会给出26的输出。问题是什么?@svs,很好的回答,问题是,是否需要递归?谢谢。:)添加二进制numb时@LinMa的可能重复手动的ER和带进位的ER向左波动,为什么它们最终总是停止波动并归零?答案是一样的。谢谢你,你能指出一个测试用例来说明我的代码中的问题吗?8和8碰巧起作用,因为进位(16
)和和位(0
)添加时不会携带,所以这里正好可以使用。^
。很好的捕获目标,为什么递归可以解决这个问题?我的意思是我们如何递归证明,携带将减少到零?很好的捕获保罗,为什么递归可以解决这个问题?我的意思是我们如何递归证明,携带将减少到零?@LinMa,你可以正式证明在每个add\u no\u arithm
中,参数的总和总是相同的(=a+b
)和b
的lat位慢慢变为0
s@LinMa是的,一个完整的证明是我和svs的评论的结合。b
并没有减少。右边的零的数量在增加,所以它必须达到零。@LinMa你可以打印出b
的值,看看你得到了什么。它们并没有减少。当你这样做时,1+3
的b
值为3
,2
,4
,0
。二进制值分别为011
,010
,100
,000
。这些值以0
,1
,2
,3
零结尾。因为0的数字位于右侧n步i
始终至少是i-1
(并且所涉及的位数是固定的),您必须达到零。@LinMa假设b
以t
零结尾。那么a和b
也将以t
零结尾,因为0&anything==0
。
add(no_arithm(18, 6))
a == 01
b == 11
sum = a^b == 10
carry = (a&b) << 1 == 10
sum ^ carry == 00 // wrong answer! 1 + 3 == 4