正数、负数和补码_正数原码反码补码

正数、负数和补码_正数原码反码补码计算机中,正数、负数是怎么区分的呢,如何存放正数和负数?这里,就要用到补码这个概念了,先给出结论吧:正数和负数在计算机其实都是使用补码来存放的,并且在计算机中是没有减法运算的,减法实际上就是补码直接相加。正数和负数的补码补码是计算机存放数据之前对数据做了一种转换操作得到的,与补码相关的几个名词还有原码、反码:1、原码:字节的最高位为符号位,其余表示数值大小,最简单;2、反码:正数的反码和原码一样,负数的反码除最高位符号位外,其他位都取反;3、补码:在反码的基础上加1,这样可以方便计算机进行计算,可

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

计算机中,正数、负数是怎么区分的呢,如何存放正数和负数?这里,就要用到补码这个概念了,先给出结论吧:正数和负数在计算机其实都是使用补码来存放的,并且在计算机中是没有减法运算的,减法实际上就是补码直接相加

正数和负数的补码

补码是计算机存放数据之前对数据做了一种转换操作得到的,与补码相关的几个名词还有原码、反码:

1、原码:字节的最高位为符号位,其余表示数值大小,最简单;
2、反码:正数的反码和原码一样,负数的反码除最高位符号位外,其他位都取反;
3、补码:在反码的基础上加1,这样可以方便计算机进行计算,可以让**最高位符号位都能参与计算**;

Jetbrains全家桶1年46,售后保障稳定

正数的补码就是原码本身,负数的补码是其反码加1,我们以C语言为例:

# short占用两字节内存,最高位为符号位
short a = 8;
short b = -8;
原码 补码
a 0000 0000 0000 1000 0000 0000 0000 1000
b 1000 0000 0000 1000 1111 1111 1111 1000

得到了a、b的补码,我们来模拟一下计算机算一下8-8的值,其实就是直接把a b的补码相加:
0000 0000 0000 1000 + 1111 1111 1111 1000 = 1 0000 0000 0000 0000
由于short总共只有两字节,所以结果中的最高位 1 要舍弃,最后得到0000 0000 0000 0000,也就是0

整数反转

介绍完了正数和负数的存储方式,下面说一下整数反转的问题。以C语言的有符号数为例:

int a = 0x80000000;

int型总共占4字节,因此内存中的a变量应该是下面这样子:

1000 0000 0000 0000 0000 0000 0000 0000

这串二进制数字如果直接按照数学规则转成十进制的话,应该是 2147483648,但是根据之前的定义我们知道,有符号数的最高字节应该是符号位,所以对于计算机而言,这个二进制数是一个负数,所以上面这个二进制串其实是一个负数的补码形式,因此如果我们直接输出a的十进制会得到一个负数,这其实就是整数反转(int的取值范围是-2147483648 ~ 2147483647,2147483648超出了这个范围)。
我们可以手动把上面的二进制串当作补码,反向转换一下,补码 – 1再取反码即可得到原码。
首先计算负数反码,也就是补码-1,也就是补码加上-1的补码,:

  1000 0000 0000 0000 0000 0000 0000 0000
+ 1111 1111 1111 1111 1111 1111 1111 1111
------------------------------------------
1 0111 1111 1111 1111 1111 1111 1111 1111

(ps:
这里我们发现符号位已经溢出了,这是因为补码计算中符号位是可以参加计算的,我们始终以结果的最高位作为符号位,不过在C语言环境中,如果直接用0x80000000 – 1,其实是会把溢出的符号位舍弃掉(因为我们要把结果存入一个int型的四字节变量里),也就是会得到:0111 1111 1111 1111 1111 1111 1111 1111,转成十进制就是2147483647)

然后我们把反码转成原码(最高位是符号位,符号位外的取反):

1 0111 1111 1111 1111 1111 1111 1111 1111
转为:
1 1000 0000 0000 0000 0000 0000 0000 0000

因此得到结果 -2147483648
也就是说,直接输出a的话会得到-2147483648:

printf("%d", a);
输出结果:
-2147483648

综上,我们可以知道整数反转为什么会发生
在C语言中,如果我们定义一个int a,然后赋值一个超过了2147483647的正数,那么a在存放这个数字的时候,符号位会发生变化——计算机只会保留二进制数字的最后32位,把前面的都舍弃掉,然后把截取后的二进制数的最高位视为符号位,因此导致实际存放的数字会发生正负数反转,比如:

int a = 2147483647 + 1;
printf("%d", a);
输出结果:
-2147483648

使用负数补码正确存放十进制大正数

了解了正、负数在计算机内存中的存放方式以及整数反转,那么如何在不改变数据类型的前提下正确存放一个十进制大正数到内存里呢?
这个场景其实会存在于进程间数据交互的情况,比如我用一个python脚本发送了一个大正数到C语言开发的一个接口,然后这个数字超过了int能表示的最大的正数,但实际上二进制长度并没有超过int的内存大小。
其实,其实如果不需要关心数据格式化输出的正负和数字多少,只关心二进制数据是否正确的话,我们只需要保证二进制数据一样就可以了,比如我们想把正数2147483649存到int型变量里:

2147483648的数学方法转成二进制为1000 0000 0000 0000 0000 0000 0000 0001

如果我们只要想办法在int变量的内存中放一样的二进制数据,就相当于实现了2147483649的存放,只不过格式化输出这个变量还是会有问题,但二进制数据是一致的~
我们知道1000 0000 0000 0000 0000 0000 0000 0001转成int型十进制,对应的数字为-2147483647,因此如果我们想存放2147483649到int里,应该使用负数补码来赋值,也就是说要把十进制大正数的数学意义的二进制数据看做是负数补码,然后转成相应的负数来赋值,比如2147483649的二进制如果当做负数补码,对应的负数为-2147483647,可得出转换公式伪代码:
int new = old – 232(old为大正数)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213939.html原文链接:https://javaforall.net

(1)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java 事务注解(java自定义注解实现)

    @Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Transactional(rollbackFor=Exception.class,noRo…

    2022年4月15日
    35
  • 测试18

    测试18文章目录系统测试概述功能测试性能测试负载测试压力测试性能测试、压力测试、负载测试的关系兼容性测试安全测试健壮性测试配置测试可用性测试文档测试系统测试概述系统测试的定义将已

    2022年7月4日
    27
  • 电商新宠—广告电商,转化产品的流量聚体地「建议收藏」

    电商新宠—广告电商,转化产品的流量聚体地「建议收藏」现在市面上通过看广告赚点零花钱的项目也是片地一把抓,在各大平台看广告,间接给平台赚钱,却不能给自己带来一些好处;而真正的并没有让消费者能长期的去坚持去做,一个月下来看广告收益也就十多二十元块钱,使大多数平台变得暗淡下去,最后无人问津。目前又听说在市面上流传了一个很火热的广告变现模式——广告电商,结合了“社交电商+广告分佣”,通过在平台购买商品,赠送同等或者一定量的积分,达到不同的门槛,可以根据不同的积分门槛看不同的广告(每天3分钟),实现广告变现,提现到微信、支付宝和对接的第三方支付服务平台。最终实现广告主

    2022年6月22日
    34
  • 2021年最好用&完全免费的图片压缩网站、软件推荐(包括GIF)

    2021年最好用&完全免费的图片压缩网站、软件推荐(包括GIF)最近我有遇到一个很奇怪的问题因为我不是转用AppleMusic本地化听歌了????所以很多歌的歌曲信息都是我自己补充的,当然也包括封面但我在用iTunes把歌传到iPhone上来听的时候,有首歌的封面怎么都同步不过来我来回同步了几遍,还重新连接了几次,甚至换回了有线来同步,这个封面始终都还是同步不上…我就一直奇了怪了直到我想重新编辑一下封面,重新添加,我才发现…好家伙,一张封面竟然有18M!?比我MP3本身都要大了,难怪我添加不上呢完全被它小小的外表给欺骗了我后来把图片

    2022年6月18日
    22
  • linux mail发送邮件_linux命令行收发email

    linux mail发送邮件_linux命令行收发email一、mail命令1.配置 vim /etc/mail.rc文件尾增加以下内容 setfrom=1968089885@qq.com smtp=”smtp.qq.com”setsmtp-auth-user=”1968089885@qq.com”smtp-auth-password=”123456″setsmtp-auth=login说

    2022年10月20日
    0
  • 在C#代码中应用Log4Net 中配置文件的解释

    在C#代码中应用Log4Net 中配置文件的解释

    2022年3月12日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号