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

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)


相关推荐

  • Windows程序设计:MFC 、Winform 和 WPF 比较[通俗易懂]

    MFC生成本机代码,自然是很快,可是消息循环减缓了界面显示速度。WinForm封装了win32的api,多次进行P/invoke操作(大部分使用p/invoke操作封装),速度慢。WPF是一种新的模型,不再使用win32模型,自己新建模型,使用dx作为新的显示技术,直接访问驱动程序,加快了运行速度,可是,这种模型,需要支持dx9的显卡,硬件要求高(你还能找到现代机器不支持dx9的吗?)…

  • 稀疏数组

    稀疏数组

  • Squid 代理服务器之 ACL 访问控制

    Squid 代理服务器之 ACL 访问控制文章目录1.ACL访问控制方式2.ACL规则优先级3.ACL的定义步骤4.定义访问控制列表4.1方法一4.2方法二1.ACL访问控制方式根据源地址、目标URL、文件类型等定义列表格式为:acl列表名称列表类型列表内容…针对已定义的acl列表进行限制格式为:http_accessallow或deny列表名称…2.ACL规则优先级一个用户访问代理服务器时,Squid会以从上至下的顺序匹配Squid中定义的所有规则列表,

  • centOS7安装nginx及nginx配置「建议收藏」

    centOS7安装nginx及nginx配置「建议收藏」安装所需插件1、安装gccgcc是linux下的编译器在此不多做解释,感兴趣的小伙伴可以去查一下相关资料,它可以编译C,C++,Ada,ObjectC和Java等语言命令:查看gcc版本gcc-v一般阿里云的centOS7里面是都有的,没有安装的话会提示命令找不到,安装命令:yum-yinstallgcc2、pcre、pcre-…

  • 前端js面试题(基础)「建议收藏」

    前端js面试题(基础)「建议收藏」1、js中使用typeof能得到哪些类型?——undefined、string、number、boolean、object、function2、===和==分别在何时使用?//==的使用情况为以下2种(其他情况下推荐使用===)if(obj.a==null){ //相当于obj.a===null||obj.a===undefined}functionfn(a,b){ i…

  • WSAStartup函数

    WSAStartup(MAKEWORD(2,2),&wsd)

发表回复

您的电子邮箱地址不会被公开。

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