【发布时间】:2016-10-02 07:04:58
【问题描述】:
这是一个 C89 项目,其中LONG_IS_64BIT 被定义当(且仅当)long 是 64 位,即包含从 -2^63-1 到 2^63 的所有整数-1。否则(按照 C 标准)它包含从 -2^31-1 到 2^31-1 的所有整数。
我有一个数字n,如果定义了LONG_IS_64BIT,则保证为0到63(含),否则为0到31(含)。我想计算 2^n-1,它适合一个 long。
目前代码有(1L<<n) - 1,但在longs 很可能正好是32 位或64 位的情况下,这是未定义的行为。 (在这部分程序中n==63 几乎是不可能的,但在 32 位计算机上n==31 肯定会发生。)正确的方法是什么?
我想我可以只测试 n==31 和 n==63 但这感觉很老套。
【问题讨论】:
-
如果您希望它真正可移植,请使用硬编码常量进行 ifdef 检查。
-
@2501 是的,这就是我判断我所处的情况的方式。代码中到处都是
#ifdef LONG_IS_64BIT测试。但是我写什么而不是(1L<<n)-1?我可以使用n==31 ? 0x7FFFFFFF : (1LL<<n)-1(在另一种情况下也是如此),但这是我能做的最好的吗? -
“否则(按照 C 标准)它包含从 -2^31 到 2^31-1 的所有整数。” -- 不,C 标准不保证这一点。它保证至少 32 位,但如果正好是 32 位,则值可能会从 -(2^31-1) 变为 2^31-1。这些实现非常罕见。您是否正在寻找可以 100% 便携使用的东西,或者适合您将要处理的实现的东西?如果是后者,它们是哪些?
-
取决于你的情况下best的含义。
-
(long)((1UL << n) - 1)
标签: c undefined standards integer-overflow c89