1

我正在用 c++ 编写一个函数,它应该在传递的数字中找到最大的单个数字(inputValue)。例如,0.345 的答案是 5。但是,过了一会儿,程序将 inputValue 更改为类似于 0.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;
}
4

4 回答 4

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;
}    
于 2012-10-12T00:50:25.103 回答
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

于 2012-10-12T00:57:09.313 回答
0

不幸的是,这就是浮点数的工作方式。问题的核心是浮点数的数量是无限的。更具体地说,在 0.1 和 0.2 之间有无数个值,在 0.01 和 0.02 之间有无数个值。但是,计算机具有有限数量的位来表示浮点数(双精度数为 64 位)。因此,大多数浮点数必须近似。在任何浮点运算之后,处理器必须将结果四舍五入到它可以用 64 位表示的值。

浮点数的另一个特性是,随着数字变大,它们变得越来越不精确。这是因为相同的 64 位必须能够表示非常大的数字(1,000,000,000)和非常小的数字(0.000,000,000,001)。因此,当使用更大的数字时,舍入误差会变大。

这里的另一个问题是您正在从浮点转换为整数。这引入了更多的舍入误差。看来,当 (0.345 * 10000) 转换为整数时,结果比 3450 更接近 3449。

我建议您不要将数字转换为整数。用浮点数编写程序。您不能对浮点数使用模数 (%) 运算符来获取数字的值。而是使用 C 数学库 (cmath.h) 中的 fmod 函数。

于 2012-10-12T01:26:19.640 回答
0

正如其他答案所表明的那样,二进制浮点无法准确表示大多数十进制数。因此,您必须重新考虑您的问题陈述。一些替代方案是:

  • 该数字以双精度形式传递(特别是 64 位 IEEE-754 二进制浮点值),并且您希望找到传递的确切值的十进制表示中的最大数字。在这种情况下,用户 millimoose 建议的解决方案将起作用(前提是使用的asprintforsnprintf函数具有良好的质量,因此它不会产生阻止其产生正确舍入输出的舍入错误)。
  • 该数字作为双精度数传递,但旨在表示一个数字,该数字可以精确地表示为具有已知位数的十进制数字。在这种情况下,用户 millimoose 建议的解决方案再次起作用,将格式规范更改为将 double 转换为具有所需位数的十进制(例如,您可以使用“%.6f”而不是“%.64f”) .
  • 该函数被更改为以另一种方式传递数字,例如使用十进制浮点、作为缩放整数或作为包含十进制数字的字符串。

一旦你澄清了问题陈述,考虑如何用浮点运算来解决它可能会很有趣,而不是调用库函数来格式化输出。这可能具有教学价值(顺便说一句,可能会产生一个比调用库函数在计算上更有效的解决方案)。

于 2012-10-12T02:16:01.910 回答