为什么这个C++程序在代码::块和在线 IDE 之间返回不同的结果?

Why does this C++ program return different results between Code::Blocks and an online IDE?

本文关键字:返回 之间 IDE 结果 在线 C++ 程序 代码 为什么      更新时间:2023-10-16

在寻求C++程序将二进制数转换为整数的帮助时,@dasblinkenlight编写了以下程序。使用 Ideone IDE 和 Repl.it,我注意到它返回了预期值482.但是,使用本地 IDE(Code::Blocks在 2 台计算机上进行测试(,相同的程序返回值506。为什么会这样?

#include <iostream>
#include <cmath>
using namespace std;
int int_length(int bit_number);
int bin_to_int(int bit_number);
int main()
{
cout << bin_to_int(111100010) << endl;
return 0;
}
int int_length(int bit_number){
bool found = false;
int digit_count = 0;
while(!found){
int division = bit_number / pow(10, digit_count);
if(division < 1){
found = true;
}
else{
digit_count++;
}
}
return digit_count;
}
int bin_to_int(int bit_number){
int number_length = int_length(bit_number);
int number = 0;
for(int i = 0; i < number_length; i++){
int e = pow(10, i);
int digit = (bit_number / e) % 10;
digit = digit * pow(2, i);
number = number + digit;
}
return number;
}

pow是一个浮点函数,因此存在舍入误差的可能性。有关概述,请参阅浮点数学是否损坏?

特别是行:

int e = pow(10, i);

可能会导致问题。计算可能会变成,比如说9999.999999983732,然后当你把它截断为整数时,你会得到9999而不是10000,导致错误的结果。

可以通过检查每个循环迭代的e值(使用调试器或输出语句(来验证此假设。 对于pow(10, digit_count)的其他用途可能存在类似的问题。

修复它的一种方法是使用舍入函数,尽管 IMO 更好的解决方案是根本不使用pow。而是编写一个带有循环的函数来执行整数幂(没有用于此目的的标准函数(。

IMO 您链接到使用pow(2, i)的建议很差。尽管 2 的幂在通用系统上完全有效,但读者可能没有意识到将pow与 2 的幂以外的整数一起使用会有问题。(C++实际上确实有2的整数幂的语法,即1 << i(。

如 @M.M 所示,编写自定义幂函数会使编译器返回预期值。 @Some程序员伙计,在调试时,我注意到计算数字幂时的精度错误。

这是完全有效的代码:

#include <iostream>
using namespace std;
int int_length(int bit_number);
int bin_to_int(int bit_number);
int main()
{
cout << bin_to_int(111100010) << endl;
return 0;
}
int power(int number, int p){
if(p < 1){
return 1;
}
else if(p == 1){
return number;
}
else if(p > 1){
int result = number;
for(int i = 1; i < p; i++){
result = result * number;
}
return result;
}
}
int int_length(int bit_number){
bool found = false;
int digit_count = 0;
while(!found){
int division = bit_number / power(10, digit_count);
if(division < 1){
found = true;
}
else{
digit_count++;
}
}
return digit_count;
}
int bin_to_int(int bit_number){
int number_length = int_length(bit_number);
int number = 0;
for(int i = 0; i < number_length; i++){
int e = power(10, i);
int digit = (bit_number / e) % 10;
digit = digit * power(2, i);
number = number + digit;
}
return number;
}