原码与补码
大约 2 分钟
本文介绍计算机中的原码和补码表示法
原码表示法
将十进制数转为二进制即为源码表示,比如,将2表示为一字节8位的原码:
如果是有符号数,比如C++中的int类型,那么就需要一位来表示符号,计算机中用0表示正数,1表示负数。
这样,+2表示为:
开始的第一位表示为符号位,-2表示为:
补码表示法
虽然原码表示法人类理解起来是最容易的,但是却不利于计算机进行运算,因此计算机中实际使用的是补码表示法,补码规则也不复杂,对于正数来说,原码表示跟补码表示一致,对于负数来说,补码表示在原码的基础上,符号位保持不变,而数值部分取反加一。
例如,+2的原码表示转换为补码表示为:
-2的原码转为补码则为:
C++
中int
的表示范围
计算清楚了原码和补码表示之后我们来计算C++
中的int
表示范围。
首先,int
型数据在C++
语言g++
编译器下使用4个字节表示:
int lengthOfInt=sizeof(int);
//结果为4(字节)
这样,一共就是4*8=32
位
32位除去一位符号位,剩余31位,那么int表示的最大正数就是:
int maxInt=pow(2,31)-1;
//maxInt=2147483647
最小负数呢?
int minInt=-(pow(2,31)-1)
//minInt=-2147483647
你觉得是这样吗?
如果你觉得是的话,你就错了,首先考虑+0的原码表示:
那么-0
呢
你会发现,0有两种表示,这样其实是一种浪费,因为在计算机中,把-0表示为最小的负数,其补码
你会发现这个数已经超过32位产生溢出了,因而实际的表示就是:
好了,现在你已经理解了原理了,那么求得以下的结果你应该不会意外了吧:
//求解int的范围
#include <iostream>
#include<cmath>
#include<limits>
int main(char* args,char** argv){
std::cout<<"Size of int(Bytes):"<<sizeof(int)<<std::endl;
std::cout<<"Max of int:"<<std::to_string(int(pow(2,31)-1))<<std::endl;
std::cout<<"Min of int:"<<std::to_string(int(pow(-2,31)))<<std::endl;
std::cout<<"Max of INT:"<<INT_MAX<<std::endl;
std::cout<<"Min of INT:"<<INT_MIN<<std::endl;
return 0;
}
使用g++编译:
g++ range_of_int.cpp -o range_of_int.exe
运行:
$./range_of_int.exe
Size of int(Bytes):4
Max of int:2147483647
Min of int:-2147483648
Max of INT:2147483647
Min of INT:-2147483648