【007】C++编程必知:原码、补码、反码的全面解读

引言


💡 作者简介:专注于C/C++高性能程序设计和开发,理论与代码实践结合,让世界没有难学的技术。包括C/C++、Linux、MySQL、Redis、TCP/IP、协程、网络编程等。
👉
🎖️ CSDN实力新星,社区专家博主
👉
🔔 专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。
👉
🔔 专栏地址:C++从零开始到精通
👉
🔔 博客主页:https://blog.csdn.net/Long_xu


🔔 上一篇:【006】C++数据类型之进制间的转换

🔔 下一篇:【008】C++数据类型之重要关键字详解

一、原码、补码、反码的概述

计算机存储的是数据的补码。

  • 原码:计算机中对数字的二进制定点表示方法。比如123的原码是0111 1011。

  • 无符号数:原码=反码=补码。

  • 有符号数:要分正数和负数,正数的最高位为0,负数的最高位为1。其中,正数的原码、反码、补码都是相同的;负数的反码等于原码的符号数(最高位)不变,其他位取反;补码等于反码+1。
    比如:-123的原码是1111 1011,反码为1000 0100,补码为1000 0101。

原码、补码和反码都是用于计算机表示有符号整数的方法。

  • 原码:最高位表示符号位,0为正数,1为负数,其余位表示数值。例如,+3的8位原码为00000011,-3的8位原码为10000011。

  • 反码:在原码基础上,负数的表示方法改为将除了符号位以外的所有位取反(即0变1,1变0)。例如,-3的8位反码为11111100。

  • 补码:在反码基础上再加1得到的结果,即负数的补码是其对应正数的原码按位取反再加1。例如,-3的8位补码为11111101。

负数在计算机中以补码形式存储;非负数在计算机中以原码形式存储。

二、为什么要使用补码?

使用补码可以简化计算机中的运算逻辑,同时还能避免原码和反码中出现的“零”问题,即正数的反码和补码等于原码,而负数的反码和补码不等于原码,因此没有正零和负零的区别。

(1)统一了 0 的编码:

+0补码:0000 0000
-0补码:0000 0000

(2)将减法运算变加法运算:

// 没有补码的情况
100000 1010
-61000 0110
---------------
---- 1001 0000
// 结果是16,有问题
// 有了补码
100000 1010
-61111 1010
---------------
---- 0000 0100
// 溢出位会被移除,结果等于4,满足运算结果

三、对数据的存

负数在计算机中以补码的方式存储。

非负数、八进制数、十六进制数等在计算机以原码的方式存储。

示例:

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
	short data=-10;
	cout<<bitset<16>(data)<<endl;
	data=10;
	cout<<bitset<16>(data)<<endl;
	data=0x80;
	cout<<bitset<16>(data)<<endl;
	return 0;
}

输出:

1111111111110110
0000000000001010
0000000010000000

四、对数据的取

  • 如果是对无符号变量进行取值,输出内存的原样数据。
  • 如果是对有符号变量进行取值,系统会去看内存的最高位,如果最高位为0表明是正数,内存原样输出。如果最高位是1表示负数,将内存数据求补码(得到原码)输出。

示例:

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
	unsigned short data = -10;
	cout << bitset<16>(data) << endl;
	cout << dec << data << endl;
	data = 10;
	cout << bitset<16>(data) << endl;
	cout << dec << data << endl;
	short data2 = 0x8080;
	cout << bitset<16>(data2) << endl;
	cout << data2 << endl;
	return 0;
}

输出:

1111111111110110
65526
0000000000001010
10
1000000010000000
-32640

五、总结

原码是数值的二进制表示方法,其中最高位表示符号位,0表示正数,1表示负数。

补码是为了解决原码运算中存在的符号位带来的问题而提出的一种方法。在补码中,正数的补码与原码相同,而负数的补码则是其对应正数的反码加1。

反码也是为了解决原码运算中存在的符号位带来的问题而提出的一种方法。在反码中,正数的反码与原码相同,而负数的反码则是将其对应正数的二进制表示中每一位取反。但是,反码存在一个问题:它有两个0表示+0和-0,这会导致计算机在进行数学运算时出现不确定性。

补码是目前计算机内部存储和运算使用的一种数值表示方法,因为它可以避免出现不确定性的情况。而原码和反码则只在理论上有一定的意义,在实际编程中很少使用。
在这里插入图片描述

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion Long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值