- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
void times(unsigned short int time)
{
hours=time>>11;
minutes=((time<<5)>>10);
}
time
成为24446
输出值为
期望值是
这段代码中正在进行什么内部处理?
24446
的二进制文件是0101111101111110
Time>>11
给出 01011
这意味着 11
.
((Time<<5)>>10)
给出 111011
这意味着 59
.
但是这里还发生了什么?
最佳答案
What else is going on here?
如果time
是unsigned short
, 之间有一个重要的区别
minutes=((time<<5)>>10);
和
unsigned short temp = time << 5;
minutes = temp >> 10;
在这两个表达式中,time << 5
计算为 int
,因为整数提升规则。 [注释 1 和 2]。
在第一个表达式中,这个 int
然后将结果右移 10。在第二个表达式中,对 unsigned short temp
的赋值将结果缩小为 short
,然后右移 10。
所以在第二个表达式中,高阶位被删除(通过转换为 unsigned short
),而在第一个表达式中,如果 int
则它们不会被删除。比 short
宽.
第一个表达式还有另一个重要的警告。由于整数提升可能会改变 unsigned short
进入 int
,中间值可能有符号,在这种情况下,如果左移足够大,则可能会溢出。 (在这种情况下,它不是。)然后右移可能应用于负数,结果是“实现定义的”;许多实现将负数的右移行为定义为对数字进行符号扩展。这也可能导致意外。
注意事项:
假设int
比 short
宽.如果unsigned int
和 unsigned short
宽度相同,不会发生转换,您也看不到您描述的差异。 C 标准(使用 C11 草案)的 §6.3.1.1/2 中描述了“整数提升”:
If an
int
can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to anint
; otherwise, it is converted to anunsigned
. These are called the integer promotions. All other types are unchanged by the integer promotions.
int
整数提升规则有效地使得无法直接使用小于 int
的类型进行任何算术计算。 ,尽管编译器可能会使用 what-if
使用子字操作码的规则。在那种情况下,它们必须产生与使用提升值产生的结果相同的结果;这对于无符号加法和乘法很容易,但对于移位就比较棘手。
位移运算符是算术运算语义的一个异常(exception)。对于大多数算术运算,C 标准要求在执行运算之前应用“通常的算术转换”。通常的算术转换,除其他外,保证两个操作数具有相同的类型,这也将是结果的类型。对于位移位,标准只要求对两个操作数执行整数提升,并且结果将具有左操作数的类型。那是因为移位运算符不是对称的。对于几乎所有的体系结构,不存在不适合 unsigned char 的移位的有效右操作数,显然不需要左右操作数的类型甚至符号相同。
在任何情况下,与所有算术运算符一样,将执行整数提升(至少)。所以你不会看到比 int
窄的中间结果.
关于c - 关于左移和右移运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080351/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!