Morse's Site
513 字
3 分钟
负数在计算机中的表示方式
2020-03-19
无标签

有这样一道题. 问下面打印的值为多少?

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. 取负数绝对值的正数, 然后取反.
    2. 将取反后的值 + 1.

使用补码表示法: 对于一个字节来说, 取值范围为 -128(1000 000)~127(0111 111)

负数在计算机中的表示方式
https://fuwari.vercel.app/posts/blogs/minus/
作者
Morse Hsiao
发布于
2020-03-19
许可协议
CC BY-NC-SA 4.0