1. Int 在计算机中占 4 Byte, 共 32 位, 最大正数为 2147483647, 最小负数为 -2147483648
2. 正数存储在计算机中的形式为原码,最大正数的十六进制形式为 0X7FFFFFFF. 第一位为7, 二进制位 0111, 最高位为符号位, 所以正数的最高位为0
3. 负数在计算机的存储形式为补码, 最小负数为0XFFFFFFFF, 第一位是F, 二进制为 1111, 负数的最高位是1
4. 大学时变反加一背的滚瓜烂熟, -x 可以通过 x 的二进制取反加一最高位置 1 获得
5. 溢出. 0X7FFFFFFF + 1 == 0X80000000, 由最大正数变成最小负数
主要考察溢出处理, 我在处理溢出时用了很多的判断语句, 写的甚是不雅
int atoi(const char *str) { if(!strlen(str)) return 0; bool neg = false; int cur = 0; int res = 0, num=0; while(str[cur] == ' ') cur++; if(str[cur]=='-') { neg = true; cur++; } else if(str[cur]=='+') { cur++; }else{} while(isNum(str[cur], num)) { if( MAXN/10 > res) { res = res * 10 + num; }else if( MAXN/10 == res) { if(neg) { if(num >=8) return MINN; else res = res * 10 + num; }else{ if(num>=7) return MAXN; else res = res * 10 + num; } }else{ if(neg) return MINN; else return MAXN; } cur++; } if(neg) return (-1)*res; else return res; }
1. 先假设所求是正数, 将二进制看出正数的原码表示
2. 假如最高位是 1, 说明所求数字实际为负数, 那么我们对 res 减一变反, 得到所求数字的绝对值再乘以 -1 即可
3. 注意, 对二进制进行操作和对十进制操作是等价的, 在这个地方想了很久. 因为变量 res 实际上只是以十进制的形式存下了二进制的数据, 当所求数字为正数时, 万事大吉, res 即为所求. 当所求为负数时, 那么 res 是没有意义的, 只是简单的用十进制形式存了某个二进制的数, 我们对其进行位操作, 减一, 求反. 得到其绝对值都相当于直接对二进制进行操作
4. 细节. 对二进制求反可以直接异或 0X11111111
for(int i = 30; i >= 0; i --) { res = res*2 + (record[i]%3); } // 负数, 按位取反, 末尾加一的逆过程 if( record[31] %3 ) { res = (res - 1)^(0x7FFFFFFF); res = -1 * res; }