【问题标题】:Unknown system bitsize for int, how to create maskint的未知系统位大小,如何创建掩码
【发布时间】:2021-04-14 13:20:59
【问题描述】:

我想只为 MSB 创建一个掩码,但是操作系统上 int 的宽度假设是未知的,因此您不能假设为 32 位。

见下文

    // THE FOLLOWING FAILS BECAUSE OF SYSTEM IMPLEMENTING A LOGICAL 
    // RIGHT SHIFT
    // Idea is 
    //     1. 0 inverted = all 1's
    //     2. Arithmetic shift right
    //     3. Then invert again to preseve MSB '1'
    const int unsigned mask = ~(~0>>1); // FAIL, because of logic shift

假设是 16 位系统

  1. ~0 给 FFFF
  2. ~0>>1 给 7FFF
  3. ~(~0 >> 1) 给8000

【问题讨论】:

  • 您在寻找intunsigned 的MSBit? (它们不必相同。)正在寻找 intunsigned 掩码?
  • @chux。如果系统具有 8、16、32 或 64 位的 int,那么我希望代码获得 msb。 Mikecat 有答案
  • Wes Taylor-Rendal,Mikecat 的答案提供了无符号的 MSBit,它很少与您的 int 目标不同。此外,该答案不适用于 8 位,也可能不适用于 16 位。

标签: c bit mask portability


【解决方案1】:

您应该添加一个u 后缀以使移位的内容无符号,以便执行逻辑右移而不是算术右移。

const int unsigned mask = ~(~0u>>1);

【讨论】:

  • 也许是“后缀”?
  • @grapes 谢谢,已修复。
  • 依赖于INT_MAX*2 + 1 == UINT_MAX非常常见 实现细节。 C 不需要但无处不在的东西。
  • 这解决了问题。我想类型转换需要在作业的 RHS 上进行。
【解决方案2】:

您可以将(无符号)值 1 移动类型中的位数减 1(即对于 32 位类型,MSB 将为 1 << 31) .要获取位数,请结合使用 sizeof 运算符和 CHAR_BIT 常量 (defined in <limits.h>):

const unsigned int MSB = 1u << (sizeof(unsigned int) * CHAR_BIT - 1);

【讨论】:

    【解决方案3】:

    INT_MAX0111...1111int 位模式(具有一定宽度)* 适用于所有实现。

    要形成1000...0000,请反转这些位。

    ~INT_MAX
    

    上面提到了undefined beahvior (UB)。
    最好寻找无符号或更宽的类型。

    unsigned mask = ~(unsigned) INT_MAX;
    

    在稀有机器上,INT_MAX == UINT_MAX,等等,寻找更广泛的类型:

    long long = ~(long long) INT_MAX;
    

    在稀有的机器上(闻所未闻),INT_MAX == LONG_MAX也是正确的,那么我们就不走运了。


    迂腐:稀有机器在int/unsigned 上使用填充,因此最好使用(U)INT_MAX 驱动代码而不是sizeof


    *也许还有一些填充位 - 非常罕见。

    【讨论】:

    • 这是使用预编译器吗?
    • @WesTaylor-Rendal 取决于工具集,但很可能是。为什么这是一个问题?
    猜你喜欢
    • 2012-02-04
    • 1970-01-01
    • 2013-04-12
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    相关资源
    最近更新 更多