【问题标题】:Behavior of integer promotion during bitwise operations按位运算期间整数提升的行为
【发布时间】:2020-09-01 00:11:45
【问题描述】:

当对小于int 的算术类型执行按位运算时,它会自动提升为int

std::uint8_t a = 42;
auto b = a | 0x0f;
// b will be of type int

我无法确定这次促销期间究竟发生了什么,特别是因为它正在从无符号整数转换为有符号整数。 a 的数值是否会保持一致,可能会改变二进制表示?或者二进制表示会保持一致,可能会导致不同的数值?

是否有理由将该值提升为int 而不是unsigned int?后者不会引起任何这种混乱。

【问题讨论】:

  • 是不是因为42 被假定为intint | intint?我会尝试使用a | 0x0f
  • @tadman 抱歉,这就是我的本意。
  • @chux-ReinstateMonica 但如果它是一样的,它仍然被提升为int?
  • 我不认为促销活动完全取决于您正在执行的操作。
  • @3Dave 0x0f 是一个整数常量。数字的大小无关紧要,除非添加了一些限定后缀,否则它将被视为int

标签: c++ bit-manipulation bitwise-operators integer-promotion


【解决方案1】:

整数在提升后具有相同的值。提升的类型首先必须能够存储源类型的所有值(可能更多)才能做到这一点。特别是,这意味着无符号值在提升后永远不会变为负数,如果int 太小,则提升的类型可能是unsigned int。但请注意,std::uint8_t 将始终提升为 int,因为它始终足够大。

当整数提升发生在有符号整数上时,负值的“二进制表示”将被符号扩展(更多的 1)。例如,std::int8_t a = -1;a & 0b100000000 != 0,即使二进制表示只是0b11111111。但这不会发生在无符号值或有符号正值上。

对象表示(当您 memcpy 到 char 数组时)可能会在提升后发生变化。这在有符号的情况下很容易看到,但在无符号的情况下,由于字节顺序,字节可能采用不同的顺序。

【讨论】:

    【解决方案2】:

    当对小于 int 的算术类型执行按位运算时,它会自动提升为 int。

    正确1。此外,这适用于所有算术运算。不仅仅是按位运算。

    a的数值会保持一致

    是的。

    可能会改变二进制表示?

    取决于您对二进制表示的期望。每个位将具有与相应的原始位相同的值,按重要性顺序排列。但是字节的内存顺序在小端系统上会发生变化。

    是否有理由将该值提升为 int

    是的。在this 答案中引用的ANSI C 基本原理中解释了这种设计选择。简而言之,这使价值在所有促销活动中保持一致。


    1从技术上讲,它可以在某些系统上在某些条件下被提升为 unsigned int。更具体地说,较低等级的整数类型被提升为 int 或 unsigned int。 Char 和 short 的等级低于 int,无论它们更小还是相同大小。当原始值不能以 int 类型表示时,它会被提升为 unsigned int。这可能发生在 unsigned char 和/或 unsigned short 大小与 int 相同的系统上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-27
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多