负数的表示方法总结:
/
正数的反码和补码都与原码相同。
而负数的反码为对该数的原码除符号位外各位取反。
负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
下面是书上原文:
原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
正零和负零的补码相同,[+0]补=[-0]补=0000 0000B
//
c语言中负数在内存中的存储:
以补码的形式存储,举个例子:
short int a = 0xffff;
short int b = -1;
此时,两个变量在内存中的值均为0xffff,实际上,对于存储器而言,—1与0xffff在内存中的存储数据是一样的,均为0xffff。
可以有如下理解:
在给有符号变量赋值时,当给定值的最高位为1时,将此值视为负数且为补码,以给定值存储,当最高位为0时,将此值视为正数,以给定值存储。(给定值显式给出负号时,此最高位就是1)
/
设备间传输数据时,有时一个数据并不完全是有效数据,有效数据只是占用了高几位或者低几位,例如:
UNIT16 data; //bit11为符号位 bit10MSB=2560
用位段定义即为(以大端为例)
type define
{
UNIT16 bake:4;//未定义的无效数据
UNIT16 sign:1;//符号位
UNIT16 data1:11;//除符号位外的有效数据
}
Data_Struct
那么如何正确的获取这个值呢(暂不考虑具体应用下的实际值,即忽略MSB)?
分析一下,如果传输的值为正数,则直接可以用data&0x0fff得到结果,如果是负数呢,此时有效数据一般默认是补码,要想得到正确的值,需要进行特殊处理,即(short
int)(data<<4)/pow(2,4)
即将无符号数左移4位,此时定义的符号位在最高位,强制类型转换,则把(data<<4)视负数的补码形式,除以pow(2,4),即右移4位,负数的右移不移动符号位,故仍为负数。
故,无论正数还是负数,均可以用(short int)(data<<4)/pow(2,4)正确地获取数值。