题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
知识点
1)异或就是不带进位的加法
2)计算进位:通过与结果左移一位,
3)不能是负数:
4)关于0xFFFF
low16 = (unsigned short ) (number>>16);
high16 = (unsigned short) (number&0xFFFF)
上式整体就是将number的低4字节分成两半,其中高的两字节存入low16,低的存入high16。& 0xFFFF
的操作是取低16位。&是按位进行与计算,而0xffff转化为二进制为1111 1111 1111 1111
进行计算后实际是取得number的低16位的值。
5) ~取反码;^异或
int main() { unsigned int uint; int i = -1; uint = i; printf("%x %d ", uint, i); //输出ffffffff -1 uint = 0xffffffff; i = uint; printf("%x %d ", uint, i); //输出ffffffff -1 int j = -1; printf("%x ", (~j)); //输出0 int k = 1; printf("%x ", (~k)); //输出0xfffffffe char c = 1; printf("%d ", (~c)); //输出-2
这里其实i在内存中是有符号的,我们知道内存中存储是补码,如果按uint读取,都是整数补码与原码相同。如果按照i读取,内存中的数值为补码表示,所以0xFFFFFFFF是一个负数的补码。负数从补码求原码,最高符号位不变,保持 1, 其余各位求反,末尾加1,也就是 0xFFFFFFFF,二进制为:11111111 11111111 11111111 11111111
-> 10000000 00000000 00000000 00000000
-> 10000000 00000000 00000000 00000001
再来看一个例子练习,~(-1),先将-1求补码,即1111 1111 1111 1111,然后取反0000 0000 0000 0000,即为0。
再附一个取反运算,这里要注意的是,数据的存储是反码格式,所以如果是负数的话,我们先要计算反码再取反。
代码
# -*- coding:utf-8 -*- class Solution: def Add(self, num1, num2): # write code here if num1 is None or num2 is None: return None while num2 !=0: sums = num1 ^ num2 //无进位加法 num2=(num1&num2)<<1 //进位 num1=sums&0xFFFFFFFF if num1>>31 == 0: return num1 else: return num1-4294967296 //负数