Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 就像无符号整数溢出一样。是什么原因造成的?_C++_Integer_Overflow_Limit - Fatal编程技术网

C++ 就像无符号整数溢出一样。是什么原因造成的?

C++ 就像无符号整数溢出一样。是什么原因造成的?,c++,integer,overflow,limit,C++,Integer,Overflow,Limit,我有一个函数,它生成一个指定数量的所谓“三角形数”。如果我打印出deque的后记,数字会增加,跳下,然后再增加。当我上升时,三角形的数字永远不会变低,所以一定有某种溢出发生。我试图通过添加行if(toPush>INT_MAX)返回I-1来修复它尝试在结果溢出时停止函数生成更多数字(并返回它生成的数字)。这不起作用,但是,输出仍然不正确(增加一段时间,跳到一个较低的数字,然后再次增加)。我加的那句话实际上似乎什么都没做。未联系到返回。有人知道这里发生了什么吗 #include <iostre

我有一个函数,它生成一个指定数量的所谓“三角形数”。如果我打印出deque的后记,数字会增加,跳下,然后再增加。当我上升时,三角形的数字永远不会变低,所以一定有某种溢出发生。我试图通过添加行
if(toPush>INT_MAX)返回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-generateTriangleNumber(std::deque&triangleNumber,无符号int-generateCount){
for(unsigned int i=1;i int_MAX)返回i-1;
三角形编号。向后推(顶推);
}
返回生成计数;
}

在Visual C++中,代码> int (当然,<代码>未签名INT/COM>)是64位计算机上的32位。
使用
无符号long-long
uint64\u t
使用64位值。

第92682个三角形数已经大于
UINT32\u MAX
。但是这里的罪魁祸首要早得多,在计算
i*(i+1)
时。在这里,65536三角形数的计算溢出。如果我们询问Python的本机bignum支持:

>>> 2**16 * (2**16+1) > 0xffffffff
True
哎呀。然后,如果你检查你存储的数字,你会看到你的序列下降回低值。要尝试模仿标准对本例行为的描述,请使用Python:

>>> (int(2**16 * (2**16+1)) % 0xffffffff) >> 1
32768
这就是你将看到的65536三角形数字的值,这是不正确的

检测溢出的一种方法是确保生成的数字序列是单调的;即,如果生成的第N个三角形编号严格大于第(N-1)个三角形编号


为了避免溢出,您可以使用64位变量来生成和存储这两个变量,或者如果需要大量的三角形数,可以使用一个大的数字库。

INT\u MAX
有符号INT
的最大值。它大约是
unsigned int
UINT\u MAX
)最大值的一半。您对
toPush
的计算可能会比
UINT\u MAX
高得多,因为您将该值平方(如果该值接近
INT\u MAX
,则结果将比
toPush
所能容纳的
UINT\u MAX
大得多)。在这种情况下,
toPush
环绕并产生比前一个更小的值

首先,您与
INT\u MAX
的比较是有缺陷的,因为您的类型是
unsigned INT
,而不是
signed INT
。其次,即使是与
UINT_MAX
的比较也不正确,因为这意味着
toPush
(比较表达式的左操作数)可以保持高于其最大值的值,而这是不可能的。正确的方法是将生成的数字与上一个数字进行比较。如果水位较低,你就知道你已经溢油了,你应该停下来


此外,您可能希望使用能够容纳更大范围值的类型(例如
无符号long-long
)。

i的第一个值对什么不起作用?如果你用手进行特定的计算,你会观察到什么?你如何期望任何数字严格地大于最大可能的数字?你应该检查计算的各个步骤。具体来说,如果溢出发生在
(i*(i+1))
中,您以后将无法检测到它。@Mat我认为作为一项测试,我将检查它是否大于INT_MAX,但仍然使用无符号INT。这样,希望它能在数字增长到可能大于无符号INT的大小之前找出问题。@OliCharlesworth我将尝试找出它的值这工作做得很好。我没有想到简单地检查新的数字是否大于上一个数字。我更改了密码,现在正是时候退出。