gpt4 book ai didi

c - 2^n - 1 不会溢出 long

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:37 25 4
gpt4 key购买 nike

这是一个 C89 项目,其中 LONG_IS_64BIT当(且仅当)a 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 ,但在极有可能的情况下 long s 恰好是 32 位或 64 位,这是未定义的行为。 (在这部分程序中 n==63 几乎是不可能的,但在 32 位计算机上 n==31 肯定会发生。)执行此操作的正确方法是什么?

我想我可以测试 n==31n==63但这感觉很老套。

最佳答案

如果你知道 (1L<<n)-1 的数学值适合 long ,您可以通过计算值减一,然后加一,而不是计算值加一,然后减一,来确保不会溢出。

n == 0 ? 1 : ((1L<<n-1)-1<<1)+1

这很复杂,如果 n == 0 需要特殊的外壳来避免左移一个负值,但至少它能为您提供所需的值(value)。

或者,您可以使用右移:

#ifdef LONG_IS_64BIT
0x7FFFFFFFFFFFFFFF>>(63-n)
#else
0x7FFFFFFF>>(31-n)
#endif

您不能使用 LONG_MAX如果它可能比您预期的要大,请在这里。

但实际上,@melpomene 的评论使用 unsigned long应该够好了。它具有与 long 相同数量的值位的平台在编写标准时已经不常见了。如果您已经假设 long将有恰好 32 位或恰好 64 位,您可能不应该担心更深奥的实现。

关于c - 2^n - 1 不会溢出 long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39814664/

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