通过在 GNU C++17 中以不同的方式(几乎相似)进行相同的计算,我得到了不同的答案
I am getting different answer by doing the same calculation in different ways ( which are almost similar ) in GNU C++17
我基本上是想找到 2 乘以 5e+8 除以 3 得到的商得到的数。我尝试了几种方法,如 GNU C++17 代码片段所示,并得到了正确的结果仅在方法 2 和 4 中回答。我最初期望它是某种溢出情况,但是 signed int 可以存储的最大数量比 2e+9 多一点,这比我处理的数字大得多所以我认为问题可能出在其他地方。如果有人可以提供帮助,那就太好了。提前致谢:)
using namespace std;
int main(){
// I basically wan't to calculate: 2 * 500000000/3 ( 2 * 5e+8 / 3)
// Approach 1
cout<<2 * 500000000 / 3<<"\n"; // output : 333333333 (nine 3s) WRONG!
// Approach 2
int a = 500000000/3; // output : 333333332 (eight 3s) CORRECT!
cout<<2 * a<<"\n";
// Approach 3
a = 2 * 500000000/3; // output : 333333333 (nine 3s) WRONG!
cout<<a<<"\n";
// Approach 4
cout<<500000000 / 3 * 2<<"\n"; // output : 333333332 (eight 3s) CORRECT!
}
我们可以验证这两个答案实际上都是正确的。
(2*500,000,000)/3 = (1000,000,000)/3=333,333,333
和
(500,000,000/3)*2 = (166,666,666)*2 =333,333,332
这与 C++ 整数除法总是向下取整有关,与溢出无关。可以说 333,333,333 是 "real" 答案 333,333,333.333...
更准确的近似值
操作顺序很重要。当你计算 2 * 500000000 / 3
时,它等于
floor(floor(2 * 500000000)/3)
(在实数运算的数学意义上),而第二种方法 2 * (500000000/3)
的计算等于
floor(2 * floor(500000000/3)).
这是因为每个整数算术运算都是总是然后向零舍入(对于非负结果与floor
相同)。
方法三相当于方法一,方法四相当于方法二
我基本上是想找到 2 乘以 5e+8 除以 3 得到的商得到的数。我尝试了几种方法,如 GNU C++17 代码片段所示,并得到了正确的结果仅在方法 2 和 4 中回答。我最初期望它是某种溢出情况,但是 signed int 可以存储的最大数量比 2e+9 多一点,这比我处理的数字大得多所以我认为问题可能出在其他地方。如果有人可以提供帮助,那就太好了。提前致谢:)
using namespace std;
int main(){
// I basically wan't to calculate: 2 * 500000000/3 ( 2 * 5e+8 / 3)
// Approach 1
cout<<2 * 500000000 / 3<<"\n"; // output : 333333333 (nine 3s) WRONG!
// Approach 2
int a = 500000000/3; // output : 333333332 (eight 3s) CORRECT!
cout<<2 * a<<"\n";
// Approach 3
a = 2 * 500000000/3; // output : 333333333 (nine 3s) WRONG!
cout<<a<<"\n";
// Approach 4
cout<<500000000 / 3 * 2<<"\n"; // output : 333333332 (eight 3s) CORRECT!
}
我们可以验证这两个答案实际上都是正确的。
(2*500,000,000)/3 = (1000,000,000)/3=333,333,333
和
(500,000,000/3)*2 = (166,666,666)*2 =333,333,332
这与 C++ 整数除法总是向下取整有关,与溢出无关。可以说 333,333,333 是 "real" 答案 333,333,333.333...
更准确的近似值操作顺序很重要。当你计算 2 * 500000000 / 3
时,它等于
floor(floor(2 * 500000000)/3)
(在实数运算的数学意义上),而第二种方法 2 * (500000000/3)
的计算等于
floor(2 * floor(500000000/3)).
这是因为每个整数算术运算都是总是然后向零舍入(对于非负结果与floor
相同)。
方法三相当于方法一,方法四相当于方法二