作者: 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', rssi, rssi);
此处,因为打印的是%d. 所以会临时扩展
0.
之前对窄数据类型向宽数据类型转换转换时,符号扩展,零扩展稍有了解,具体什么时候用符号扩展,什么地方用零扩展,并不清楚。所以常用按位与(&) 按位或(|) 等操作来保证扩展部分与编程思路的统一。
这次在使用iBeacon协议时,信号强度的dbm值保存在一个字节中。有时作为原码,有时又要求补码。为了验证,常要printf出来。 这下就要求把零扩展和符号扩展搞清楚。
1. 何时使用零扩展,何时使用符号扩展:
当窄数据类型为:有符号数据类型时,扩展为宽数据类型时,使用符号扩展。
当窄数据类型为:无符号数据类型时,扩展为宽数据类型时,使用零扩展。
例1: 有符号数扩展(符号扩展)
int8_t rssi = 0xBE;
int rssi_4byte = 0;
rssi_4byte = rssi;
解析:
rssi为8位有符号数,则使用符号扩展。
0xBE:
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', rssi, rssi);
此处,因为打印的是%d. 所以会临时扩展
