gpt4 book ai didi

c - 关于左移和右移运算符

转载 作者:太空狗 更新时间:2023-10-29 16:12:26 24 4
gpt4 key购买 nike

void times(unsigned short int time)
{
hours=time>>11;
minutes=((time<<5)>>10);
}

接受输入 time成为24446

输出值为

小时 = 11

分钟 = 763

期望值是

小时 = 11

分钟 = 59

这段代码中正在进行什么内部处理?

24446 的二进制文件是0101111101111110

Time>>11给出 01011这意味着 11 .

((Time<<5)>>10)给出 111011这意味着 59 .

但是这里还发生了什么?

最佳答案

What else is going on here?

如果timeunsigned 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 ,中间值可能有符号,在这种情况下,如果左移足够大,则可能会溢出。 (在这种情况下,它不是。)然后右移可能应用于负数,结果是“实现定义的”;许多实现将负数的右移行为定义为对数字进行符号扩展。这也可能导致意外。


注意事项:

  1. 假设intshort 宽.如果unsigned intunsigned 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 an int; otherwise, it is converted to an unsigned
    int
    . These are called the integer promotions. All other types are unchanged by the integer promotions.

    整数提升规则有效地使得无法直接使用小于 int 的类型进行任何算术计算。 ,尽管编译器可能会使用 what-if使用子字操作码的规则。在那种情况下,它们必须产生与使用提升值产生的结果相同的结果;这对于无符号加法和乘法很容易,但对于移位就比较棘手。

  2. 位移运算符是算术运算语义的一个异常(exception)。对于大多数算术运算,C 标准要求在执行运算之前应用“通常的算术转换”。通常的算术转换,除其他外,保证两个操作数具有相同的类型,这也将是结果的类型。对于位移位,标准只要求对两个操作数执行整数提升,并且结果将具有左操作数的类型。那是因为移位运算符不是对称的。对于几乎所有的体系结构,不存在不适合 unsigned char 的移位的有效右操作数,显然不需要左右操作数的类型甚至符号相同。

    在任何情况下,与所有算术运算符一样,将执行整数提升(至少)。所以你不会看到比 int 窄的中间结果.

关于c - 关于左移和右移运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080351/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com