剑指offer-[编程题]不用加减乘除做加法(python2实现及解析)

正负数判断及还原

正数与边界数 按位与(&) 操作后 仍得到这个数本身:

负数与边界数 按位与(&) 操作后 得到的是对应二进制数的形式值
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
~((负数 & 0xFFFFFFFF) ^ 0xFFFFFFFF) = 这个负数 (这个结果直接为补码,计算机认补码,所以才要这么做,让结果为补码)
例:~((-15 & 0xFFFFFFFF) ^ 0xFFFFFFFF) = 11111111111111111111111111110001(补码) ,对应的十进制为-15
-15 & 0xFFFFFFFF = 4294967281 为-15补码的形式值

为了便于理解,以一个小边界为例:

241 对应的二进制数为: 11110001

答案中,通过查看符号位(最高位,即与0x7FFFFFF比较大小)判断a为正数还是负数,正数则直接返回。负数则返回~(a^0xFFFFFFFF)。 (注: ~ 表示按位取反)

此处操作最终返回的是原来负数的值:

11110001^0xFFFFFFFF -----> 00001110
~(00001110) -----> 11110001(补码) ,对应的十进制数是 -15
此处有一个规律:
~n = -(n+1)
参考下面链接:
https://blog.csdn.net/Strive_Chuan/article/details/79242010

作者:Cris_Lee卡卡卡
来源:CSDN
原文:https://blog.csdn.net/lrs1353281004/article/details/87192205
版权声明:本文为博主原创文章,转载请附上博文链接!

题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

思路:1.num1 ^ num2 结果为相加不进位的那些位。
2.num1 & num2 结果为相加进位的那些位,让这些位左移一位,则表达式为(num1 & num2) << 1。
3.检查num1 & num2结果是否为0,为0则没有进位了,最后结果为进位位或不进位,也可以在num2 == 0的情况下用^异或取代|或。

# -*- coding:utf-8 -*-
class Solution:
	def Add(self, num1, num2):
		if not num1:
			return num2
		if not num2:
			return num1
		while num2:    #没有进位了跳出循环
			n1 = num1 ^ num2
			n2 = (num1 & num2) << 1
			num1 = n1 & 0xFFFFFFFF    #因为python整数类型可以表示无限位边界需要人为设置边界,避免死循环,设置成32位应该是考虑到其他语言的特点,测试样例中不会出现超过32位整型的数, 4 * 8 = 32位,1个F表示8位实际上,把边界调大的话,不会影响最终结果。-15 & 0xFFFFFFFF = 2 ** 32 - 15 , -15 & 0xF = 2 ** 4 - 15,因为界定边界后,n1为负数的话,num1得到的是n1的**形式值**,所以还要num1 - 2 ** 32 ,结果为十进制。 等价于~(num1 ^ 0xFFFFFFFF) 结果为补码
			num2 = n2 & 0xFFFFFFFF
		return num1 if num1 >> 31 == 0 else num1 - 2 ** 32

方法二:

# -*- coding:utf-8 -*-
class Solution:
	def Add(self, num1, num2):
		return sum([num1, num2])

猜你喜欢

转载自blog.csdn.net/weixin_44088837/article/details/87987775