深入理解有符号数与无符号数的强制转换

        在计算机系统中,数值一律用补码来储存,是因为使用补码可以将符号位和数值域统一处理,同时加法和减法统一处理。然而我们平常看到的都是二进制的原码,下面是原码,反码,补码的概念。

原码:是一种计算机中对数字的二进制定点表示方法,平时正常用的二进制表示法。

反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码:正数的补码与其原码相同;负数的补码等于其反码+1。

一、C语言中8位有符号类型的整数值范围为什么是从-128~127

      8位无符号数范围为:0 ~ 255,这是没有什么疑问的,二进制原码表示为 1111 1111,因为无符号数没有符号位,又因为它是正数,计算结果就是255。

      而有符号类型的范围按照上述来说,直观的可以表示为 1111 1111~0111 1111,最高位是符号位,所以结果就是-127~127,但是-128到底是怎么来的呢?

      在开头我们提到了计算机中都是用补码储存数据的,而原码只是平常直观展示给我们的,所以我们要理解-128怎么来的,就要从补码的方向入手。在计算机中,不仅仅原码中的最高有效位为符号位,补码的最高有效位也是符号位,而这两种符号位既有相同也有不同。我们以4位有符号类型为例来讲解补码的数据到底是怎么表示的。

      在原码中,最高位(符号位)只表示正负,其他位表示数值。比如:1001,值为-1.

      而在补码中,最高位(符号位)不仅仅表示正负,也表示数值,同样的:1001,在补码的值为-7。

      而这就是问题的关键,大家觉得怎么把补码中的1001转换为十进制中的-7,是不是要从补码变成反码在变成原码,1001->1000->1111==-7。其实不然,补码也可以直接计算。在补码中,最高位是1,它的最高位是负数,其他位全是正数,而补码的计算结果是最高位的值加上其他位的值。就比如补码中的1001,其实就是 -1*2的3次幂 + 0*2的2次幂 + 0*2的1次幂 + 1 =-8+0+0+1=-7。再比如补码中的0101,就是 -0*2的3次幂 + 1*2的2次幂 + 0*2的1次幂 + 1=0+4+0+1=5。

      现在大家明白了补码直接转换为十进制的方法,那么大家觉得4位有符号数的补码最大值和最小值是多少?没错,最小值是1000,最大值是0111,就是-8~7。而在原码中确是1111~0111,是-7~7。但是计算机真正的是以补码储存的,所以表示范围肯定是-8~7,而-8既没有原码也没有反码,他只有补码。把上述的结果代入到我们的8位有符号数中,我们就知道-128~127并不是原码表示的范围,而是计算机中补码的范围,而-128也没有真正的原码表示。

二、深入理解有符号数和无符号数的强制转换。

      其实大家读到这里也差不多明白了强制转换的原理,因为我们平常看到的有符号数都是原码,而储存在计算机中的都是补码,所以当一个数进行强制转换的时候,它的数值可能会变,但是它的位模式不变,也就是它在计算机中的补码是不变的。我们举个例子:有符号数-3的原码是1011,它的反码是1100,补码是1101。当他转换为无符号类型时补码不变,又因为无符号数的原码既是反码也是补码,所以它转换为无符号数的二进制就是1101->1101->1101,而无符号数没有符号位,每个位的数值相加得13,所以有符号数-3就转换为无符号数13。我相信通过以上例子大家已经明白了转换的原理,然后大家在找一个大于0的有符号数,把他转换为无符号数。你会发现,数值是一样的,所以就得出以下规律:

       当有符号数<0时,无符号数=有符号数+2的n次幂(n为二进制的位数)

       当有符号数>0时,无符号数=有符号数

了解计算机的原理才能更好的学习新的知识,大家在平常计算的话其实就记住最后的结论就好。

综上,我想大家应该明白的差不多了,如果还有人有些许疑问,可以放到评论区里一起讨论呀。

感到有帮助的友友们点个赞呗

猜你喜欢

转载自blog.csdn.net/H0893_888/article/details/131815771