似乎是由特定情况下的整数溢出引起的错误
An error that seems to be caused by an integer overflow for a specific case
我是这个网站的新手。我环顾四周寻找与我相似的问题,但发现 none 所以我自己要问一个新问题。我希望我的格式正确。
我正在编写的程序的一部分总结了一些大数字。这是我目前拥有的代码:
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
的值是 unsigned 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;
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
但我的实际程序并非如此,因为我会收到一个错误,告诉我这是溢出,对吗?我不知道在这里做什么,我已经尝试了我能想到的一切。出了什么问题?
谢谢。
关于这样的陈述:
unsigned long int asdf = 937504347 + 709551656;
将 int 值 937504347
和 709551656
加在一起创建 int
结果,然后将其加载到 unsigned long
变量。为避免在 int
-add 阶段溢出,您应该已经使用了正确的类型,例如:
unsigned long int asdf = 937504347UL + 709551656UL;
你似乎已经知道这一点,因为你得到了编译时错误,因为编译器已经知道你要添加的值。
但是,您的论点是,您会看到编译器在编译时不知道知道的任意值的相同结果,这是不正确的。它只会添加值和翻转无符号值。它也可能会翻转带符号的值,但从技术上讲,这是未定义的行为,所以如果它格式化您的硬盘,请不要感到惊讶:-)
在任何情况下,该标准只保证较高级别的类型具有更大的 或等于 范围到较低级别。一个 unsigned long
只 需要 是 32 位(更准确地说,有一个可以用 32 位表示的范围)。如果您想要保证大小,请使用 cstdint
中的 uintX_t
类型。 uint64_t
类型应该大大扩展您的范围,为您提供大约 18 quintillion (18,446,744,073,709,551,615
) 的最高保证值。
我是这个网站的新手。我环顾四周寻找与我相似的问题,但发现 none 所以我自己要问一个新问题。我希望我的格式正确。
我正在编写的程序的一部分总结了一些大数字。这是我目前拥有的代码:
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
的值是 unsigned 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;
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
但我的实际程序并非如此,因为我会收到一个错误,告诉我这是溢出,对吗?我不知道在这里做什么,我已经尝试了我能想到的一切。出了什么问题?
谢谢。
关于这样的陈述:
unsigned long int asdf = 937504347 + 709551656;
将 int 值 937504347
和 709551656
加在一起创建 int
结果,然后将其加载到 unsigned long
变量。为避免在 int
-add 阶段溢出,您应该已经使用了正确的类型,例如:
unsigned long int asdf = 937504347UL + 709551656UL;
你似乎已经知道这一点,因为你得到了编译时错误,因为编译器已经知道你要添加的值。
但是,您的论点是,您会看到编译器在编译时不知道知道的任意值的相同结果,这是不正确的。它只会添加值和翻转无符号值。它也可能会翻转带符号的值,但从技术上讲,这是未定义的行为,所以如果它格式化您的硬盘,请不要感到惊讶:-)
在任何情况下,该标准只保证较高级别的类型具有更大的 或等于 范围到较低级别。一个 unsigned long
只 需要 是 32 位(更准确地说,有一个可以用 32 位表示的范围)。如果您想要保证大小,请使用 cstdint
中的 uintX_t
类型。 uint64_t
类型应该大大扩展您的范围,为您提供大约 18 quintillion (18,446,744,073,709,551,615
) 的最高保证值。