unsigned int(无符号整型)
[数据类型]
描述
在 Uno 和其他基于 ATMEGA 的板子上,无符号整数与有符号整数(ints)在存储上是相同的,都存储一个 2 字节的值。不过,无符号整数不存储负数,只存储正数,因此其有效范围是 0 到 65,535((216) - 1)。
Due 则存储一个 4 字节(32 位)的值,范围从 0 到 4,294,967,295(232 - 1)。
无符号整数和有符号整数之间的区别在于对最高位(符号位)的解释方式。在 Arduino 的 int 类型(有符号整型)中,如果高位是 1,则该数字被解释为负数,而其他 15 位则使用二进制补码来解释。
语法
unsigned int var = val;
参数:
var:变量名。
val:要分配给该变量的值。
示例代码
unsigned int ledPin = 13;
注意事项和警告
当无符号变量超过其最大容量时,它们会“回滚”到 0,反之亦然:
unsigned int x;
x = 0;
x = x - 1; // x 的值现在是 65535 - 向负方向回滚
x = x + 1; // x 的值现在是 0 - 回滚
使用无符号变量进行数学运算可能会产生意外的结果,即使你的无符号变量从未回滚过。
微控制器(MCU)应用以下规则:
计算是在目标变量的范围内进行的。例如,如果目标变量是有符号的,它将执行有符号数学运算,即使两个输入变量都是无符号的。
然而,对于需要中间结果的计算,代码没有指定中间结果的范围。在这种情况下,微控制器将对中间结果执行无符号数学运算,因为两个输入都是无符号的!
例如:
unsigned int x = 5;
unsigned int y = 10;
int result;
result = x - y; // 5 - 10 = -5,如预期
result = (x - y) / 2; // 无符号数学中5 - 10是65530! 65530/2 = 32765
译注:C 语言中,当不同类型的数据进行运算的时候,就会发生强制或隐式类型转换,通常是低精度的数据类型扩展到高精度的。上面说的其实有点问题,两个无符号数运算不会先扩展成有符号数的,而是将无符号数运算结果直接赋值给有符号数。5 - 10 等于多少?对于 16 位无符号数来说,等于 0xFFFB,也就是 65531。在 C 语言中,当一个无符号整数(例如 unsigned int )被赋值给一个相同长度的有符号整数(例如 int )时,隐式类型转换的规则通常遵循位模式保持不变的原则。也就是说,底层的二进制表示(位模式)直接从无符号数复制到有符号数。所以,会被按补码方式来解释,结果就是 -5。65531 / 2 = 32,765,即 0x7FFD,将它赋值给有符号数,按照补码解释结果是正数。要想不出错,要使用强制类型转换或其他方法。
为什么要使用无符号数变量?
- 回滚行为是期望的,例如计数器。
- 有符号变量稍微小了一点,但你想避免使用 long/float 带来的内存和速度损失。
扩展阅读
|