513 字
3 分钟
负数在计算机中的表示方式
有这样一道题. 问下面打印的值为多少?
a uint := 1
b uint := 2
print(a - b)
相关知识
如何表示一个有符号的数(即正数, 负数, 0)
方法一: 符号量表示法, 用最高位表示符号, 比如: 0 为正数, 1 为负数.
这种表示方法简单直接, 但是有两个缺点:
* 0的表示方法有两种: +0 和 -0
* 浪费了一个位数, 即最高位始终都沦为符号的表示. 所以当使用一个字节(int8)表示一个数字, 那么这种方法的表示范围为: -127~+127
方法二: 补码表示法, 这种方法也是现在最常用的表示方法. 这种方法也避免了上一种方法的两个缺点.
那么补码表示法是如何表示表示的呢? 我们继续使用1个字节来说明(int8).
* 对于正数和0来说. 最高为仍然为0, 所以可以表示 0~+127个数字, 与方法一相同.
* 对于负数. 对abs(num)取反, 然后加1.
如 -1, 当用一个字节表示, 因为1为 0000 0001
, 取反得 1111 1110
, 那么-1 = 1111 1110
+ 1 = 1111 1111
所以使用补码表示法. 对于一个字节来说. 可以表示的数字范围为: -128~127
解题
那么对于开始那道题来说, 首先 1-2 = -1.
- -1如果使用补码表示的, 先对1取反(^1), 然后在加1.
- int类型, 对于32位系统则为32个1, 64位则为64个1.
- 因为uint表示无符号, 则需要把最高位1变为0, 所以对于32位系统, 31个1 = 2^32-1, 对于64位操作系统为 63个1 = 2^64 - 1
总结
补码表示法:
对于正数和零, 最高位0. 其余位为此数字的二进制数
对于负数.
- 取负数绝对值的正数, 然后取反.
- 将取反后的值 + 1.
使用补码表示法: 对于一个字节来说, 取值范围为 -128(1000 000)~127(0111 111)
负数在计算机中的表示方式
https://fuwari.vercel.app/posts/blogs/minus/