我正在用c ++编写一个函数,它应该找到传递的数字中最大的单个数字(inputValue)。例如,.345的答案是5.但是,一段时间后,程序正在将inputValue更改为.3449行(并且最大的数字然后设置为9)。我不知道为什么会这样。任何帮助解决这个问题将不胜感激。
这是我的.hpp文件中的函数
void LargeInput(const double inputValue)
//Function to find the largest value of the input
{
int tempMax = 0,//Value that the temporary max number is in loop
digit = 0,//Value of numbers after the decimal place
test = 0,
powerOten = 10;//Number multiplied by so that the next digit can be checked
double number = inputValue;//A variable that can be changed in the function
cout << "The number is still " << number << endl;
for (int k = 1; k <= 6; k++)
{
test = (number*powerOten);
cout << "test: " << test << endl;
digit = test % 10;
cout << (static_cast<int>(number*powerOten)) << endl;
if (tempMax < digit)
tempMax = digit;
powerOten *= 10;
}
return;
}
答案 0 :(得分:1)
您无法在计算机中精确表示实数(双精度) - 它们需要近似。如果您将功能更改为long或int,则不会出现任何不准确之处。这对于你的问题的上下文来说似乎很自然,你只是看数字而不是数字,所以.345可以是345并得到相同的结果。
试试这个:
int get_largest_digit(int n) {
int largest = 0;
while (n > 0) {
int x = n % 10;
if (x > largest) largest = x;
n /= 10;
}
return largest;
}
答案 1 :(得分:0)
这是因为实数的分数分量是1/2 ^ n的形式。因此,您可以获得非常接近您想要的值,但您永远无法获得精确的值,如1/3。
通常使用整数并进行转换(例如1000 = 1),因此如果您使用数字1333,则可以printf("%d.%d", 1333/1000, 1333 % 1000)
打印出1.333。
顺便说一句,第一句是简化浮点数实际表示的方式。欲了解更多信息,请查看; http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
答案 2 :(得分:0)
不幸的是,这是浮点数如何工作。问题的核心是存在无限数量的浮点数。更具体地说,在0.1和0.2之间存在无限数量的值,并且在0.01和0.02之间存在无限数量的值。但是,计算机具有有限数量的位来表示浮点数(对于双精度数,为64位)。因此,大多数浮点数必须近似。在任何浮点运算之后,处理器必须将结果舍入为可以用64位表示的值。
浮点数的另一个特性是随着数字变大,它们的精确度会越来越低。这是因为相同的64位必须能够代表非常大的数字(1,000,000,000)和非常小的数字(0.000,000,000,001)。因此,使用更大的数字时,舍入误差会变大。
这里的另一个问题是您正在从浮点转换为整数。这引入了更多的舍入误差。似乎当(0.345 * 10000)转换为整数时,结果接近3449而不是3450.
我建议您不要将数字转换为整数。根据浮点数编写程序。您不能对浮点数使用模数(%)运算符来获取数字值。而是在C数学库(cmath.h)中使用fmod函数。
答案 3 :(得分:0)
正如其他答案所示,二进制浮点无法准确表示大多数十进制数。因此,您必须重新考虑您的问题陈述。一些替代方案是:
asprintf
或snprintf
函数具有良好的质量,因此它不会产生舍入错误,从而无法生成正确的舍入输出) 一旦澄清了问题陈述,考虑如何使用浮点算法解决它,而不是为格式化输出调用库函数可能会很有趣。这很可能具有教学价值(顺便说一下,这可能会产生一种计算效率比调用库函数更高效的解决方案。)