-5 的 8 位补码是多少?
11111011 11111011,十六进制 0xFB。
在线原码/反码/补码计算器,一次算出原码、反码、补码与移码四种表示,支持 4/8/16/32/64 位。也可反过来粘贴 11111011 或 0xFB,看它按无符号、原码、反码、补码、移码分别读作多少。-128 在 8 位下没有原码和反码,本工具会明确标出并解释为什么。全程浏览器本地计算。
输入一个有符号整数。四种表示会同时算出来——你不必事先知道自己的系统用的是哪一种。
| 编码 | 位串 | 十六进制 |
|---|---|---|
| 原码 | 1000 0101 | 85 |
| 反码 | 1111 1010 | FA |
| 补码 | 1111 1011 | FB |
| 移码 | 0111 1011 | 7B |
原码和反码各拿一个位型去表示负零,所以它们能表示的数比补码少一个,够不到最负的那个值。
你在内存 dump 或寄存器里看到一个字节,却不知道它该怎么读。粘进来,同一串位在每一种解释下的含义会一次全部列出——哪一种才对取决于产生它的系统,所以这里全都给你。
| 读作 | 数值 |
|---|---|
| 无符号 | 251 |
| 原码 | -123 |
| 反码 | -4 |
| 补码 | -5 |
| 移码 | 123 |
由上方工具所用的同一份引擎算出,所以两者不可能对不上。
| 十进制 | 原码 | 反码 | 补码 | 移码 | 十六进制 |
|---|---|---|---|---|---|
| 127 | 0111 1111 | 0111 1111 | 0111 1111 | 1111 1111 | 7F |
| 100 | 0110 0100 | 0110 0100 | 0110 0100 | 1110 0100 | 64 |
| 10 | 0000 1010 | 0000 1010 | 0000 1010 | 1000 1010 | 0A |
| 5 | 0000 0101 | 0000 0101 | 0000 0101 | 1000 0101 | 05 |
| 1 | 0000 0001 | 0000 0001 | 0000 0001 | 1000 0001 | 01 |
| 0 | 0000 0000 | 0000 0000 | 0000 0000 | 1000 0000 | 00 |
| -1 | 1000 0001 | 1111 1110 | 1111 1111 | 0111 1111 | FF |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 | 0111 1011 | FB |
| -10 | 1000 1010 | 1111 0101 | 1111 0110 | 0111 0110 | F6 |
| -100 | 1110 0100 | 1001 1011 | 1001 1100 | 0001 1100 | 9C |
| -127 | 1111 1111 | 1000 0000 | 1000 0001 | 0000 0001 | 81 |
| -128 | — | — | 1000 0000 | 0000 0000 | 80 |
| 位宽 | 补码 / 移码 | 原码 / 反码 |
|---|---|---|
| 4 | -8 … 7 | -7 … 7 |
| 8 | -128 … 127 | -127 … 127 |
| 16 | -32768 … 32767 | -32767 … 32767 |
| 32 | -2147483648 … 2147483647 | -2147483647 … 2147483647 |
| 64 | -9223372036854775808 … 9223372036854775807 | -9223372036854775807 … 9223372036854775807 |
由 Go Tools 工程团队构建并验证。
11111011 11111011,十六进制 0xFB。
-128 … 127 补码是 -128 到 127;原码和反码都是 -127 到 127。
无符号值 − 2^n 最高位是 0 就按无符号读;是 1 就用无符号读数减去 2^n。
-1 或 255 按有符号字节是 -1,按无符号字节是 255。光看位定不了。
补码回答的是一个硬件问题而不是数学问题:怎样存负数,才能让已经造好的加法器继续用?办法是用 2^n - x 的位型来表示 -x。这样加法在模 2^n 意义下自动回绕并落到正确结果上,符号不需要任何特例,减法也就不必再单独造一套电路。
由此引出两个后果,两个都会在真实的 bug 里出现。第一,范围是不对称的:8 位覆盖 -128 到 127 而不是 -128 到 128,因为位型总量要分配,而补码没有负零去把两边凑齐。第二,符号不是一个可以单独摘掉的标志位——11111011 的最高位是 1,但它的值是 -5 而不是 -123,读一个负数必须解释整个字,只看一位是不够的。
原码和反码是竞争中落败的两种设计。它们仍然值得了解,一是因为 IEEE 754 浮点数保留了原码式的布局,二是因为只有摆在一起对照,补码才显得是必然而不是随意的选择。
// -5 as an 8-bit byte, three ways to arrive at the same pattern 0b00000101 // 5 ~0b00000101 // 11111010 ones' complement of 5 ~0b00000101 + 1 // 11111011 two's complement = -5 // In JavaScript the width matters: bitwise operators are 32-bit, // so anything wider has to go through BigInt. BigInt.asIntN(8, 0xFBn) // -5n BigInt.asUintN(8, -5n) // 251n BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n // C23 made two's complement mandatory for signed integers. // Before that, the other two encodings were legal but unused.
原码、反码、补码、移码同时算出。移码是多数计算器不做的那一个,而它恰好是 ADC 数据手册一直在用的那一个。
把你手上真正拿到的位串或十六进制粘进去,五种读法(含无符号)一并列出。dump 和设备报的数对不上时,需要的正是这个方向。
所有数值都用 BigInt 处理,所以 0xFFFFFFFFFFFFFF9C 得到的是 -100,而不是 32 位截断之后的某个数。
位宽 8 下的 -128 既没有原码也没有反码。表格会如实写明,而不是印一个并不表示这个数的位型。
输入 0,页面会给出零在原码和反码里的第二个位型——这是「补码为什么赢」最直观的一条证据。
8 位对照表和各位宽的取值范围是构建时渲染的,用的是驱动上面输入框的同一份引擎,所以两者不可能对不上。
BigInt.asIntN、Python 的 int.from_bytes(..., signed=True)、C 的定宽类型,对你正在写的代码给出的是权威答案。代码里用它们;手上有个值而又没开解释器的时候用本页。
它按程序声明的类型显示数值,而类型恰好是一串裸位所缺的那条信息。当字节是从线上收来、根本没有声明类型时它就帮不上忙——那正是本页要处理的情况。
它在各进制之间转换,但只处理非负数——负数在那里是被明确拒绝的,因为「进制」本身对符号怎么存没有主张。有符号表示归本页管,绝对值的进制转换归它管。
浮点数那一侧的对应工具。它用的是原码式布局而不是补码,指数还带 2^(e-1)-1 的偏移,所以两个页面回答的是关于同一个内存字的两个不同问题。
-5,位宽 8
原码 1000 0101 反码 1111 1010 补码 1111 1011 (0xFB) 移码 0111 1011
三种编码只在符号位上一致,其余全都不同。真正装进 C 的 int8_t 里的,只有补码那一行。
0xFB,位宽 8
无符号 251 原码 -123 反码 -4 补码 -5 移码 123
-128,位宽 8
原码 该位宽下没有表示 反码 该位宽下没有表示 补码 1000 0000 (0x80) 移码 0000 0000
原码和反码各拿一个位型去表示负零,所以范围是 -127 到 127,够不到 -128。在这里给出一个位型的工具是错的。
0xFFFFFFFFFFFFFF9C,位宽 64
补码 -100 无符号 18446744073709551516
超过 32 位就必须用 BigInt。JavaScript 的 |、<<、>>> 会静默截断到 32 位,这正是有些在线计算器在这里给出错误答案而不是报错的原因。
4、8、16、32 或 64。这不是显示偏好——同一串位在不同位宽下代表不同的数,选错了答案就变了。
输入一个整数,负号照写。四种编码随输入实时更新,每种同时给出十六进制形式。
把二进制串或 0x 开头的十六进制粘进反查框,就能看到这串位在每一种解释下代表什么,包括无符号读法。
页面会标出最容易翻车的两处:最负的那个值在原码和反码下没有表示,以及零在这两种编码里有第二个位型。
逐位取反得到的是反码。停在这一步就与补码差了 1,而且很难发现,因为结果看上去仍像一个合理的负数。
5 = 00000101 ~5 = 11111010 <- ones' complement, not -5
5 = 00000101 ~5 = 11111010 ~5 + 1 = 11111011 <- -5 in two's complement
JavaScript 会把位运算符的操作数截断到 32 位。高一半悄悄消失且不报错,所以结果是错的而不是缺失的。
0xFFFFFFFFFFFFFFFB // 18446744073709552000 -- the literal is already rounded ~0xFFFFFFFFFFFFFFFB + 1 // 0 -- silently wrong, expected -5
BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n
补零扩宽只有在数是正的时候才保值。负数必须把符号位复制到新增的那些位上。
int8 0xFB (-5) int16 0x00FB (251) <- zero-extended
int8 0xFB (-5) int16 0xFFFB (-5) <- sign-extended
8 位下的 -128 既没有原码也没有反码,因为这两种编码各花掉一个位型去表示负零。给它印上 10000000,是把补码的答案套在一种根本表达不了这个数的编码上。
-128 sign-magnitude: 10000000 <- that pattern means -0
-128 sign-magnitude: no representation at width 8 -128 two's complement: 10000000
0xFF9C。按无符号读是 65436,这不可能是温度。按位宽 16 看补码那一行是 -100,配合 0.1 °C 的刻度因子,传感器说的是 -10.0 °C。n-1 位当作普通无符号数读,就是数值的绝对值。范围 -(2^(n-1)-1) 到 2^(n-1)-1,对称,有两个零。IEEE 754 浮点数用的就是这种布局。2^n - 1 - x。范围和两个零都与原码相同。它的加法需要循环进位,而这正是补码要消掉的麻烦。英文里 ones' complement(反码)的撇号在 s 之后、two's complement(补码)在 s 之前,不是笔误:前者相对于全 1 的字,后者相对于一个 2 的幂。-x 存成 2^n - x。范围 -2^(n-1) 到 2^(n-1)-1,刻意不对称,只有一个零。加法、减法以及乘法低位字的运算全都与符号无关,这就是它胜出的全部理由。value + 2^(n-1),于是 -2^(n-1) 变成全 0,位型的无符号大小顺序与它们编码的数值顺序一致。它等于补码把最高位翻转。注意命名陷阱:IEEE 754 的指数字段偏移是 2^(e-1)-1,比这里用的少 1。&、|、~ 和移位的操作数转成 32 位整数再运算、再转回来,于是 64 位的值会丢掉高一半而不抛出任何错误。本页的每一次转换都在任意精度整数上完成,这也是 64 位边界值在这里是精确的原因。-(-128) 仍然是 -128。任何求绝对值的代码都得为这个输入准备好,任何测试集都该包含它。0xFB 塞进 16 位字段写成 0x00FB,-5 就变成了 251。扩宽一个有符号值意味着把符号位复制过去,得到 0xFFFB。BigInt.asIntN、Python 的 int.from_bytes(..., signed=True)、C 的定宽类型,都把意图写清楚了并且处理好了边界。手写的 ~x + 1 才是位宽 bug 的来源。2^n - x 的位型来存,这样加法和减法共用同一套电路,而且整条数轴上只有一个零。 00000101 → 11111010 → 11111011。只做取反那一步得到的就是反码,所以反码和补码永远差 1。 n 位覆盖 -2^(n-1) 到 2^(n-1)-1,因为它不像原码和反码那样浪费一个位型去表示负零,多出来的那一格落在了负数一侧。 int8_t 还是 uint8_t 去取对应那一行。 value + 2^(n-1),于是最小值变成全 0,把原始位型当无符号数排序的结果与按有符号值排序一致。它出现在 ADC/DAC 的输出和某些音频采样格式里。注意 IEEE 754 的指数字段用的偏移是 2^(e-1)-1,比这里的少 1,两个数不能互相搬用。 真值 + 2^(n-1),所以它能表示的范围与补码完全相同:8 位是 -128 到 127,4 位是 -8 到 7。变的只是位型的排布——最小值对应全 0,最大值对应全 1,把位型当无符号数从小到大排,得到的正是数值从小到大的顺序。 2^(n-1) 的偏移。 00000000 和 10000000 都表示零;在反码里是 00000000 和 11111111。于是两个数值相等的量按位比较却可能不相等。补码只有一个零,这一下消掉了一整类硬件特例。 转换工具
在线免费进制转换工具,支持二进制、八进制、十进制、十六进制及 2-36 任意进制互转。无需注册,数据不离开浏览器,即时获取结果。
转换工具
在线 chmod 计算器:Linux 文件权限在八进制(755、644)与 rwx 符号之间双向转换,实时生成可复制的 chmod 命令,并自动提示 777 等高危权限。免费使用,全部在浏览器本地完成,数据不上传。
转换工具
在浏览器中将 HEX 转 RGB、HSL、OKLCH、OKLAB 与 CMYK,一键复制任意格式。免费、免注册,您的颜色永远不会离开本页。
转换工具
在浏览器中把 HEX 颜色转成 CMYK。基于 sRGB 的朴素近似,适合印前预览。免费、免注册,您的颜色始终保留在本地。
转换工具
在浏览器中把任意 HEX 颜色转成 HSL —— 3 位、6 位以及带 alpha 的 8 位全部支持。免费、即时、免注册,您的颜色永远不会离开本页。
转换工具
把 HEX 转成 OKLCH,直接喂给 Tailwind v4 设计 token。实时输出感知均匀的三元组,带 Display P3 色域提醒。免费,纯浏览器运行。