Java_1_04

本文深入解析原码、反码和补码的概念,探讨它们在计算机内部的表示方式及运算原理,特别强调补码在解决0表示唯一性和简化计算机设计方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原码、反码和补码

机器数

即一个数在计算机中的表示形式
  • 机器数是带符号的;
    • 用该数字的最高位表示;
    • 正数为 0,负数为 1;

真值

因为机器数第一位是符号位,故机器数不代表该数的真正数值。
所以机器数对应的真正数值称为机器数的 真值

原码

即 符号位 + 真值绝对值,第一位表示符号,其余位表示数值;
[+1]原 = 0000 0001
[-1]原 = 1000 0001

反码

  • 正数
    • 正数的反码是其 原码 本身
  • 负数
    • 负数反码是其 原码符号位不变,其余位取反

补码

  • 正数
    • 正数的补码是其 原码 本身
  • 负数
    • 负数的补码是 原码 符号位不变,其余位取反,最后 +1
    • 即在其 反码 的基础上 +1

反码、补码出生背景

对于正数,其原码反码补码均相同;但对于负数,其原码反码补码均不相同;
对于原码,人脑知道第一位是符号位,可以直接用于计算;
但对计算机来说,让其识别符号位会使计算机的基础电路设计边得十分复杂! 
为简化设计,让符号位也参与运算:
	1-1=0 ——> 1+(-1)=0
如此,计算机就没有减法了

但这样会有一个问题:
如果用原码表示,符号位参与运算,对于减法来说 wrong!!!
1 - 1 = 0
1 + (-1) = 0
[00000001]原 + [10000001]原 = [10000010]原 = -2 

反码 就是为了解决 原码做减法 的问题而出现的:
[00000001]反 + [11111110]反 = [11111111]反 = [10000000]原 =0

这时,新的问题出现了:
用 反码 计算减法会出现 [10000000]原 和[00000000]原 都可以表示 0 ;

补码 就是为了解决 0 的符号位以及两个编码 的问题
1 - 1 
= 1 + (-1)  
= [00000001]原 + [10000001]原 
= [00000001]反 + [11111110]反
= [00000001]补 + [11111111]补 
= [00000000]补
= [00000000]原
= 0
如此,0 用 [00000000]补 表示,-0 则不存在了;
-128 可以用 [10000000]补 表示
  • 用 原码 和 反码 表示,[-127,127]
  • 用 补码 表示,[-128,127]

位运算

Java中,二进制数用 补码 表示!!!

位运算符

^ 异或

& 、| 、!

<< (向左位移)

将数字转换成二进制数后向左移动符号右边的位数,后边用 0 补齐!
2<<3  --- 将 2 的二进制数(2 的补码[00000010])向左位移 3 位
	  ——> [00000010] 向左位移3位 变成 [00010000](16 的 补码 )
  • 正数
    • 左移,用 0 补齐低位
  • 负数
    • 与正数相同,左移,再用 0 补齐低位

>> (向右位移)

将数字转换成二进制数后向右移动符号右边的位数,正数高位用 0 补齐,负数则用 1 补齐!
16>>2 — 将 16 的二进制数(2 的补码[00000010])向右位移 2 位
——> [00010000] 向右位移2位 变成 [00000100](4 的 补码 )

  • 正数
    • 右移,高位用 0 补齐
  • 负数
    • 右移,高位用 1 补齐

>>> (无符号右移)

  • 正数
    • 右移,用 0 补齐
  • 负数
    • 与正数一致,用 0 补齐
      ###ps:
      左移、右移在java中的优先级 仅高于 " = " ,故位运算时最好加上 括号();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值