为啥这个函数不超过值 2^31?
Posted
技术标签:
【中文标题】为啥这个函数不超过值 2^31?【英文标题】:Why doesn't this function exceed the value 2^31?为什么这个函数不超过值 2^31? 【发布时间】:2012-01-02 15:51:53 【问题描述】:幂函数(用c++编写)...
long power (long a, long b)
long result=1l;
for (int i = 0;i<b;i++)
result*=a;
return result;
现在我做一些输出测试...
cout<<power(2l,2l)<<endl;
cout<<power(2l,4l)<<endl;
cout<<power(2l,31l)<<endl;
cout<<power(2l,32l)<<endl;
cout<<power(2l,61l)<<endl;
输出:
4
16
-2147483648
0
0
好吧,长期回落到 32 位大小(而不是保持为 64 位)似乎存在一些问题。我想知道为什么这不起作用,但如果我使用 long long
类型,一切正常。
一些额外的信息:
我正在使用 C++ 和编译器 MinGW 我正在运行 64 位操作系统(Windows 7)
更新:
你们太棒了!没想到会发生这种事情。
我刚刚使用 sizeof
检查了一些任意 PDT,这就是我发现的...
cout<<sizeof(long)<<" "<<sizeof(int)<<" "<<sizeof(char)<<" "<<sizeof(long long)<<" "<<sizeof(uint64_t)<<endl;
输出:
4 4 1 8 8
所以,我的 long
和 int
看起来都是 32 位大小的。更多玩弄表明 intmax_t 类型也是 64 位的。几乎每个 PDT 的上限为 64 位,所以如果我需要表示一个 128 位整数,c++ 是否有一个内置类(类似于 Java 中的BigInteger
)?
【问题讨论】:
不要猜测 - 打印 sizeof(long) 和 sizeof(int) 的值以找出它们有多大 如果您想提出一个新问题,我建议您创建一个新问题(或者更好的是,finding a previous question on the topic)。这是一个快速链接:gmplib.org 【参考方案1】:显然,long
类型在您的环境中是 32 位。
为了解决类似问题,我建议您使用像 uint64_t
这样的类型,而不是依赖原生类型具有特定大小的假设。
编辑
回答你的第二个问题(c++ 是否有内置的 128 位整数类?):不,它没有。或者更确切地说,它没有强制要求。但是,如果实现提供了一个,您将能够使用类似uint128_t
的东西。不过,就个人而言,我还没有看到任何系统可以做到这一点。不过,有像 GMP 这样的第三方库可以提供该功能。
【讨论】:
小注释:有符号整数的溢出是未定义的行为,因此0
是可能的输入之一。改用无符号整数(如unsigned long
)会有一个环绕,结果可能不是0
(而是1
)
大金属可以拥有它们。我使用了几台(少于 5 台)具有 int 128 的研究机器。【参考方案2】:
A.尝试运行:
cout<<sizeof(long);
查看它是 32 位的。
B.我想这是您项目定义的问题。即使您在 64 位机器上工作,它也可以编译 32 位程序,因此您可以在 32 位和 64 位机器上同时使用它。 并且 long 始终是指针的大小...
C. uint64_t
是最佳实践。
【讨论】:
【参考方案3】:well long 类型占用 32 位,因此最大正值为 4294967296-1。但是您的函数计算值 5842587018385982521381124421=21^21。
【讨论】:
其实就是 2l ^ 2l 其中“l”(大写形式的 L)表示类型long
【参考方案4】:
在 C++ 和 C 中,int
的大小取决于体系结构,这都是真的,但问题是 32 位有符号 int
介于 -2^31 和 (2 ^31-1),不是 2^31。您确实溢出了一个 32 位数字。您应该改用unsigned int
。介于 0 和 (2^32-1) 之间。
【讨论】:
你说的有道理,但我的整数仍然是 32 位的:S 是的,你所说的已经死了,除了我需要 2^61 这样大的数字,即使是无符号整数也不够。以上是关于为啥这个函数不超过值 2^31?的主要内容,如果未能解决你的问题,请参考以下文章