java用的原码还是反码_Java 基础 - 原码,补码和反码

总结

1-正数的原码,反码,补码都一致;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

2-结论:机器数存储的是“补码”

3-为何机器不用“反码”进行运算?

为了“尝试”让符号位直接参与加减法运算,引入“反码”。但是很多结果是不对的。

3.1 符号位直接参与运算结果不对

想象一个8位数的"-1+3"运算,如果用反码计算 [11111110]反 + [00000011]反,无论符号位参参与运算,结果都很奇怪:

符号位参与运算:   [11111110]反 + [00000011]反 = [00000001]反 = [01111110]原  不等于 2

符号位不参与运算:[11111110]反 + [00000011]反 = [00000001]反 = [0111111]原    不等于 2

3.2 +0 -0 的问题

a43cfeae6e60aec470e3e997b346f837.png

用反码计算减法, 在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

4-为何机器使用“补码”进行运算?

为了解决反码符号位计算的错误,以及+0和-0的问题,引入“补码”。

4.1 符号位直接参与运算结果正确

想象一个8位数的"-1+3"运算,如果用补码计算:

-1+3 = [11111111]补 + [00000011]补 = [0000 0010]补 = [0000 0010]原 = 2

4.2 +0 -0 的问题

9fd917bb4dfe1e9b1c7307ed73d83073.png

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

011fd579b4cadf869a4ceb658103f657.png

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)。

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

原文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值