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

正数、负数和补码_正数原码反码补码计算机中,正数、负数是怎么区分的呢,如何存放正数和负数?这里,就要用到补码这个概念了,先给出结论吧:正数和负数在计算机其实都是使用补码来存放的,并且在计算机中是没有减法运算的,减法实际上就是补码直接相加。正数和负数的补码补码是计算机存放数据之前对数据做了一种转换操作得到的,与补码相关的几个名词还有原码、反码: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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 砸盘、销号、解散社群,Merlin Lab“跑路三连”暴露了DeFi哪些问题?

    砸盘、销号、解散社群,Merlin Lab“跑路三连”暴露了DeFi哪些问题?抛售代币、注销推特、微信群解散,昨夜BSC机枪池项目MerlinLab上演一出火速“大逃亡”。6月29日15点24分,MerlinLab遭到黑客攻击。据区块链安全公司PeckShield…

    2022年5月19日
    40
  • EagleEye_eyekey

    EagleEye_eyekey摘要:EagleEye作为阿里集团老牌的链路跟踪系统,其自身业务虽不在交易链路上,但却监控着全集团的链路状态,特别是在中间件的远程调用上,覆盖了集团绝大部分的场景,在问题排查和定位上发挥着巨大的作用,保障了各个系统的稳定性,为整个技术团队打赢这场战役保驾护航。作者:王华锋(水彧)背景 双十一一直是阿里巴巴集团每年要打的一场大战役。要打赢这场战役,技术上,不仅仅是几个应用、几个

    2022年4月19日
    61
  • vscode支持java_vscode配置go环境

    vscode支持java_vscode配置go环境VScode配置Java环境1.下载JDK方式一:手动下载JDKOracleJavaSEAdoptOpenJdkAzulZuluforAzure-EnterpriseEdition方式二:VSCode中下载JDK下载JAVA插件扩展方式一:windows平台下可以直接访问这个地址直接下载带有java插件的vscode方式二:在vscode中下载以下插件LanguageSupportforJavabyRedHatDebug

    2022年9月1日
    0
  • hive删除数据insert overwrite

    hive删除数据insert overwrite

    2021年5月13日
    150
  • 医学图像处理最全综述「建议收藏」

    目录0、引言1、病变检测2、图像分割基于深度学习的医学图像分割与检测3、图像配准图像配准的定义4、图像融合5、预测与挑战6、结论参考文献0、引言医学图像处理的对象是各种不同成像机理的医学影像,临床广泛使用的医学成像种类主要有X-射线成像(X-CT)、核磁共振成像(MRI)、核医学成像(NMI)、超声波成像(UI)四类。在目前的影像医疗诊断中,主要是通过观察一组二维切片图象去发现病变体,这往往需要借助医生的经验来判定。利用计算机图像处理技术对二维切片图象进行.

    2022年4月7日
    198
  • Spring Boot 中使用@KafkaListener并发批量接收消息[通俗易懂]

    Spring Boot 中使用@KafkaListener并发批量接收消息[通俗易懂]kakfa是我们在项目开发中经常使用的消息中间件。由于它的写性能非常高,因此,经常会碰到Kafka消息队列拥堵的情况。碰到这种情况时,有不能直接清理整改消息队列,因为还有别的服务正在使用该队列。因此只能额外启动一个相同名称的consumer-group来加快消息消费(经测试,如果该topic只有一个分区,实际上再启动一个新的消费者作用不到)。具体代码在这里,欢迎加星号,fork。官方文档……

    2022年10月15日
    0

发表回复

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

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