我是这个网站的新手。我环顾四周,发现与我的问题类似的问题,但没有找到,所以我自己问一个新问题。我希望我能正确格式化它。
我正在编写的程序的一部分总结了一些大数字。这是我当前拥有的代码:
Ball* tmp = player2->RemoveMaxNode();
if (!tmp->GetChosen())
{
cout << player2->GetHeapType() << " is chosing " << tmp->GetValue() << "-" << tmp->GetSumOfDigits() <<endl;
cout << "Adding " << tmp->GetValue() << " to ";
cout << player2->GetScore();
cout << " which should = " << tmp->GetValue() + player2->GetScore() << endl;
player2->UpdateScore(tmp->GetValue());
cout << player2->GetHeapType()<< " score now is: ";
cout << player2->GetScore();
cout << endl;
tmp->SetChosen(true);
numberOfBalls--;
j++;
// cout << endl;
}
使用我的UpdateScore()函数:
void Heap::UpdateScore(unsigned long int value)
{
this->currentScore += value;
}
这将给我输出:
AGENT1 is chosing 937504347-42
Adding 937504347 to 0 which should = 937504347
AGENT1 score now is: 937504347
AGENT1 is chosing 709551656-44
Adding 709551656 to 937504347 which should = 1647056003
AGENT1 score now is: 1647056003
AGENT1 is chosing 681463104-33
Adding 681463104 to 1647056003 which should = 2328519107
AGENT1 score now is: 2328519107
AGENT1 is chosing 672306410-29
Adding 672306410 to 2328519107 which should = 3000825517
AGENT1 score now is: 3000825517
AGENT1 is chosing 667082001-30
Adding 667082001 to 3000825517 which should = 3667907518
AGENT1 score now is: 3667907518
AGENT1 is chosing 378250713-36
Adding 378250713 to 3667907518 which should = 4046158231
AGENT1 score now is: 4046158231
AGENT1 is chosing 309421734-33
Adding 309421734 to 4046158231 which should = 60612669
AGENT1 score now is: 60612669
AGENT1 is chosing 206733105-27
Adding 206733105 to 60612669 which should = 267345774
AGENT1 score now is: 267345774
AGENT1 is chosing 151431905-29
Adding 151431905 to 267345774 which should = 418777679
AGENT1 score now is: 418777679
AGENT1 is chosing 13048925-32
Adding 13048925 to 418777679 which should = 431826604
AGENT1 score now is: 431826604
注意:破折号后的整数值是破折号前的值的数字总和。这可以忽略。我经过手动计算,所有这些都是正确的,直到得到
AGENT1 is chosing 309421734-33
Adding 309421734 to 4046158231 which should = 60612669
AGENT1 score now is: 60612669
此加法运算得出的数字应为4,355,579,965,但应为60612669。这两个数字之差为4,294,967,296,我知道这是2 ^ 32位整数的最大大小。因此,我将所有变量都更改为unsigned long int。 tmp
的值是无符号long int,而player2
的分数也是。但是,问题仍然存在,我不知道该怎么办。我以为这是一个整数溢出错误,所以我对所有要累加的整数值进行了硬编码,然后出现了溢出错误。
main.cpp: In function 'int main(int, char**)':
main.cpp:147:53: warning: integer overflow in expression [-Woverflow]
unsigned long int asdf = 937504347+709551656+681463104+672306410+667082001+378250713+309421734+206733105+151431905+13048925;
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
但是对于我的实际程序却不是这样,因为我会收到一条错误消息,告诉我它是一个溢出,对吗?我不知道该怎么办,我已经尝试了所有我能想到的东西。怎么了?
谢谢。
答案 0 :(得分:0)
关于这样的声明:
unsigned long int asdf = 937504347 + 709551656;
将 int 值937504347
和709551656
相加,创建一个int
结果,然后将其加载到unsigned long
变量中。为了避免在int
添加阶段发生溢出,您应该已经在使用正确的类型,例如:
unsigned long int asdf = 937504347UL + 709551656UL;
您似乎已经知道了这一点,因为您收到了编译时错误,因为编译器已经知道您要添加的值。
但是,对于编译器在编译时不知道的任意值,您将看到相同结果的争论是不正确的。它将仅添加值并翻转无符号值。它也可能会翻转带符号的值,但是,从技术上讲,这是未定义的行为,因此,如果它格式化了硬盘,也不要感到惊讶:-)
在任何情况下,该标准仅保证较高等级的类型具有更大的 或等于 范围到较小的等级。仅{em}要求unsigned long
为32位(更正确地说,其范围可以用32位表示)。如果要保证大小,请使用uintX_t
中的cstdint
类型。 uint64_t
类型应会大大扩展您的范围,使您可以保证的最高价值约为18亿五千万(18,446,744,073,709,551,615
)。