这是针对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,它适合在长的内部。
目前代码有(1L<<n) - 1
,但在极有可能的情况下long
s正好是32位或64位,这是未定义的行为。 (在程序n==63
的这一部分几乎是不可能的,但在32位计算机上n==31
肯定会发生。)什么是正确的方法?
我想我可以测试一下n==31
和n==63
,但感觉很糟糕。
答案 0 :(得分:2)
如果您知道long
的数学值适合n == 0 ? 1 : ((1L<<n-1)-1<<1)+1
,则可以通过计算减去1的值,然后加1,而不是计算值来确保不会溢出加一,然后减一。
n == 0
它是错综复杂的,如果#ifdef LONG_IS_64BIT
0x7FFFFFFFFFFFFFFF>>(63-n)
#else
0x7FFFFFFF>>(31-n)
#endif
需要特殊的套管以避免左移一个负值,但至少它会为你提供所需的价值。
或者,您可以使用右移:
LONG_MAX
如果它可能比您预期的要大,那么您无法使用unsigned long
。
但实际上,@ melpomene使用long
的评论应该足够好了。在编写标准时,与long
具有相同数值位的平台已经不常见了。如果您已经假定<html>
<head>
<script type="text/JavaScript">
function unload(){
alert("My Page unLoad - Destroy Variable");
}
function load() {
alert("My Page Load");
}
</script>
</head>
<body onLoad="load()">
<script type="text/javascript">
window.onbeforeunload = unload();
</script>
</body>
</html>
将具有正好32位或正好64位,那么您可能不应该担心更深奥的实现。