就像unsigned int overflow.是什么引起的?
Acting like unsigned int overflow. What is causing it?
我有这个函数,它生成一个指定数量的所谓的'三角形数'。如果我输出deque后记,数字增加,跳下来,然后再次增加。三角形数永远不会随着i的增加而降低,所以一定会发生某种溢出。我试图通过添加行if(toPush > INT_MAX) return i - 1;
来修复它,试图阻止函数生成更多的数字(并返回它生成的数字),如果结果溢出。然而,这不起作用,输出仍然是不正确的(增加一段时间,跳降到一个更低的数字,然后再次增加)。我添加的行实际上似乎没有做任何事情。无法返回。有人知道这是怎么回事吗?
#include <iostream>
#include <deque>
#include <climits>
int generateTriangleNumbers(std::deque<unsigned int> &triangleNumbers, unsigned int generateCount) {
for(unsigned int i = 1; i <= generateCount; i++) {
unsigned int toPush = (i * (i + 1)) / 2;
if(toPush > INT_MAX) return i - 1;
triangleNumbers.push_back(toPush);
}
return generateCount;
}
INT_MAX
为signed int
的最大值。约为unsigned int
(UINT_MAX
)最大值的一半。你对toPush
的计算可能会比UINT_MAX
高得多,因为你对这个值进行了平方(如果它接近INT_MAX
,那么结果将比toPush
所能容纳的UINT_MAX
大得多)。在这种情况下,toPush
环绕,结果值比前一个小。
INT_MAX
的比较是有缺陷的,因为你的类型是unsigned int
,而不是signed int
。其次,即使与UINT_MAX
进行比较也是不正确的,因为它意味着toPush
(比较表达式的左操作数)可以保存高于其最大值的值-这是不可能的。正确的方法是将生成的数字与之前的数字进行比较。如果它较低,你知道你有溢出,应该停止。
此外,您可能希望使用可以容纳更大范围值的类型(例如unsigned long long
)。
第92682个三角形数已经大于UINT32_MAX
。但这里的罪魁祸首要早得多,在i * (i + 1)
的计算中。在这里,对于65536个三角形数,计算会溢出。如果我们询问具有原生bignum支持的Python:
>>> 2**16 * (2**16+1) > 0xffffffff
True
哦。然后,如果您检查存储的数字,您将看到您的序列回落到低值。为了尝试在Python中模仿标准中对这种情况的行为的描述:
>>> (int(2**16 * (2**16+1)) % 0xffffffff) >> 1
32768
,这是您将看到的65536个三角数的值,这是不正确的。
这里检测溢出的一种方法是确保生成的数字序列是单调的;即,如果生成的第n个三角形数严格大于第(N-1)个三角形数
为了避免溢出,可以使用64位变量生成&存储它们,或者如果你需要大量的三角形数,使用一个大的数字库。
在visualc++中,int
(当然还有unsigned int
)即使在64位计算机上也是32位的。
使用unsigned long long
或uint64_t
来使用64位值
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "1L << count"是什么意思?如何使用超出"unsigned long long int? "范围的语句编号打印?
- 这里的unsigned关键字的作用是什么
- " long unsigned typedef int long ullong; "是什么意思?
- 'uintmax_t' 'size_t'和'unsigned int'转换,数据丢失是什么?
- 就像unsigned int overflow.是什么引起的?
- 将二进制文件读取到向量"unsigned char"时的模板参数是什么
- 将"unsigned char"数组转换为其"unsigned short"对应项的有效方法是什么?