龙空技术网

用C++代码帮助理解负数在计算机中的表示

二狗的随笔 192

前言:

现在兄弟们对“c语言几次方”大概比较关怀,朋友们都想要剖析一些“c语言几次方”的相关文章。那么小编在网络上网罗了一些对于“c语言几次方””的相关知识,希望咱们能喜欢,大家快快来学习一下吧!

笔者在大学里学习“计算机基础”这门课的时候,被原码、反码和补码这些概念搞得是晕头转向,最终也是似懂非懂。

但是在学习程序设计的时候,算是把负的整数在计算机中怎么表示搞清楚了

其实没那么复杂,只要记住这么几条就可以了:

将最左边的位(最高位) 看作“符号位”。

符号位为0 ,则表示是非负数,其绝对值就是除符号位以外的部分;符号位为1 ,则表示是负数,其绝对值是所有位取反(0 变 1, 1 变 0 )后再加 1 。

将一个负整数表示为二进制的方法:

设置符号位为 1,其余位等于绝对值取反再加 1

给定一个负整数的二进制表示形式,求该负整数:

该负整数的绝对值是其二进制表示形式取反再加1

( 取反加 1 后的结果要看作是正数)。

用下面这段C++代码来进一步帮助理解:

int的长度是4个字节,

也就是32个二进制位,

用十六进制表示就是8个十六进制数(每个十六进制数可以表示4个二进制位)

最左边的位是符号位,右边的31位是整数的数值,

所以整数int的范围就是 -2^31 ~ (2^31-1)

如果32个位都是1, 也就是十六进制FFFFFFFF (8个F),换算到十进制是多少呢?

套用上边的方法,第一个位是1,说明是负数;后边的二进制位都是1 (F对应1111),取反后都是0,然后加1,就是1,也就是说绝对值是1;所以8个F对应的十进制就是 -1 。

同理,一个1后边跟者31个0,也就是十六进制80000000,对应的十进制是多少呢?

第一个位是1,说明是负数;绝对值是(31个0取反+1),就是31个1+1,得到1后边跟31个0,就是2^31;所以就是 -2^31= -2147483648

还有一个有趣的事情,就是溢出,英文叫 overflow

int变量对应的最大的数是,二进制0后边跟着31个1,对应十进制的2^31-1=2147483647;

对应的十六进制数是,第一个数0111也就7,后边跟着7个F;

十六进制7FFFFFFF + 1 是多少呢?

用二进制加一下就是1后边跟着31个0,也就是我们上边计算过的80000000,也就是十进制的-2147483648

参考代码中也调用了c语言库函数cmath来计算2^31次方,然后进行类型转换,来进一步帮助理解二进制数所表示的十进制整数,就不多解释了,看看代码应该可以搞明白在做什么

参考代码:

#include <iostream>#include <cstdio>#include <cmath>using namespace std;int main (){ int a = 0xFFFFFFFF ; // -1 int b = 0x80000000 ; // -2^31 int c = 0x80000001 ; // -(2^31 -1) int d = abs(c) ; // max positive, 2^31 -1 int e = d+1 ; // max positive (2^31 -1) + 1 will overflow, result is -(2^31) printf("hexadecimal : decimal \n") ; printf("%x :%d\n", a, a) ; printf("%x :%d\n", b, b) ; printf("%x :%d\n", c, c) ; printf("%x :%d\n", d, d) ; printf("%x :%d\n", e, e) ; printf("-------------------------------------------\n") ; // double mm = pow (2.0, 31.0) ; // cmath lib 2^31 printf("double 2^31 = %lf\n", mm) ; long long m = (long long) mm ; printf("long long 2^31 = %ld\n", m) ; int n = (int) m; printf("int 2^31 = %d because of overflow\n", n) ; --m ; n = (int) m; printf("int (2^31 -1) = %d\n", n) ; m = (long long) mm ; m = 0 - m ; printf("long long (-2^31) = %ld\n", m) ; n = (int) m; printf("int (-2^31 ) = %d no overflow\n", n) ; return 0 ;}

输出结果:

hexadecimal : decimalffffffff :-180000000 :-214748364880000001 :-21474836477fffffff :214748364780000000 :-2147483648-------------------------------------------double 2^31 = 2147483648.000000long long 2^31 = 2147483648int 2^31 = -2147483648 because of overflowint (2^31 -1) = 2147483647long long (-2^31) = -2147483648int (-2^31 ) = -2147483648 no overflow

标签: #c语言几次方