Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

零扩展和符号扩展

$
0
0
作者: Sam (甄峰)  sam_code@hotmail.com

0.
之前对窄数据类型向宽数据类型转换转换时,符号扩展,零扩展稍有了解,具体什么时候用符号扩展,什么地方用零扩展,并不清楚。所以常用按位与(&) 按位或(|) 等操作来保证扩展部分与编程思路的统一。

这次在使用iBeacon协议时,信号强度的dbm值保存在一个字节中。有时作为原码,有时又要求补码。为了验证,常要printf出来。 这下就要求把零扩展和符号扩展搞清楚。


1. 何时使用零扩展,何时使用符号扩展:
当窄数据类型为:有符号数据类型时,扩展为宽数据类型时,使用符号扩展。
当窄数据类型为:无符号数据类型时,扩展为宽数据类型时,使用零扩展。

例1: 有符号数扩展(符号扩展)
int8_t rssi = 0xBE;
int rssi_4byte = 0;

rssi_4byte = rssi;
解析:
rssi为8位有符号数,则使用符号扩展。
0xBE:   10111110B. 最高位为1。所以使用1扩展到其它3个byte.
rssi_4byte: 11111111 11111111 11111111 10111110B = - 0x42 = -66.

例2:无符号数扩展(零扩展)
uint8_t rssi = 0xBE;
0xBE=10111110B
rssi_4byte: 00000000 00000000 00000000 10111110B = 0xBE = 190


例3:rssi实际使用中遇到的问题:
1个字节保存RSSI:0x9F.
它的含义其实是:1001 1111
最高位:1表示负值。 其实表示:-0x1F. = -31

如果这样处理:
int8_t rssi = 0x9F;
printf("RSSI: [%d] 0x%x\n", rssi, rssi);
此处,因为打印的是%d. 所以会临时扩展为4byte.
又因为是int8_t, 是有符号。所以会符号扩展。
rssi会被扩展为:FFFFFF9F.
所以打印结果是: RSSI [-97], 0xFFFFFF9F
这显然与希望的结果不同。

如果这样处理:
uint8_t rssi= 0x9F;
printf("RSSI: [%d] 0x%x\n", rssi, rssi);
此处,因为打印的是%d. 所以会临时扩展为4byte.
又因为是uint8_t, 是无符号。所以会零扩展。
rssi会被扩展为:0000009F.
打印结果为:RSSI [159]  0x9F.
这显然与希望的结果不同。

仔细分析下来: 0x9F 其实是 RSSI的原码。那如何得到原始值就很清晰了。
最高位是符号位,其它位是绝对值。

int8_t rssi = 0x9F;
if(rssi > 0)
{
    printf("RSSI: [%d] [0x%x]", (int)rssi, (int)rssi);
}
else
{
    printf("RSSI: [-%d] [-0x%x]", (rssi&0x7F), (rssi&0x7F));
}







附1:

原码:

 


如果机器字长为n,那么一个数的原码就是用一个n位的二进制数,其中最高位为符号位:正数为0,负数为1。剩下的n-1位表示概数的绝对值。

例如: X=+101011 , [X]原= 00101011    X=-101011 , [X]原= 10101011 
位数不够的用0补全。

PS:正数的原、反、补码都一样:0的原码跟反码都有两个,因为这里0被分为+0和-0。

反码:

 

知道了什么是原码,那反码就更是张飞吃豆芽——小菜一碟了。知道了原码,那么你只需要具备区分0跟1的能力就可以轻松求出反码,为什么呢?因为反码就是在原码的基础上,符号位不变其他位按位取反(就是0变1,1变0)就可以了。


例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100


补码:


补码也非常的简单就是在反码的基础上按照正常的加法运算加1。


例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]补=11010101


PS:0的补码是唯一的,如果机器字长为8那么[0]补=00000000。


移码:


移码最简单了,不管正负数,只要将其补码的符号位取反即可。


例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]补=11010101,[X]移=01010101






 

Viewing all articles
Browse latest Browse all 158

Trending Articles