我看了this question,但情况似乎不一样。
我在我正在编写的check register程序中有一个函数,它从用户那里读取一美元的金额,验证它不是用小数点输入的,并与用户检查它是否正确输入。不过,我得到的是,在将输入的浮点值乘以100并用(int)截断后,该值会发生变化。例如,如果输入1118.58,我可以(通过debugprintf语句)验证1118.58是否被正确扫描并分配给了amt,并且我的while条件(int)100 * amt == 100 * amt是否被正确测试为TRUE,但是在转换为整数后,整数值存储为111857。更令人困惑的是,它不会发生在每一个值上(虽然我只是在测试上做得很好,这是我看到的第一个这样改变的条目)。
我在Kubuntu 14.0464位上使用gcc,在编译命令中使用C99标准设置。
这是导致问题的函数(假设您不希望/不需要看到完整程序的1300行)。注意:为了方便起见,我在头文件中定义了布尔值和运算符——我最近发现有一种标准的方法可以这样做,但还没有转换头文件。

int get_amt (void)
{
  float amt;
  int scanned, i_amt;
  int success = FALSE;
  char yn = '\0';

  while (NOT success)
  {
    scanned = scanf("%f%*c", &amt);

    /* validate and verify amount */
    if (scanned >= 1 AND (int)100*amt == 100*amt AND amt <= 100000)
    {
      i_amt = (int)(100 * amt);
      printf("\n amt = %4.2f i_amt = %i", amt, i_amt);
      printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", i_amt/100, i_amt%100);
      scanf("%c%*c", &yn);
      if (yn == '\0' OR yn == 'Y' OR yn == 'y')
        success = TRUE;
    }
  }
  return (i_amt);
}

下面是带有debug print语句的输出示例:
Enter deposit amount (dollars and cents): $ 1118.58

 amt = 1118.58 i_amt = 111857
You entered $1118.57 -- Correct (Y/n)?

为什么会发生这种情况,我该如何解决?
在下面的注释中讨论之后,我已经将函数转换为使用整数,因此不存在浮点精度的问题(我并没有真正考虑标准浮点在64位操作系统和编译器上的精度有多低)。以下是更新版本,由于没有浮动,因此无法给出此失败:
int get_amt (void)
{
  int scanned, amt1, amt2;
  int success = FALSE;
  char yn = '\0';

  while (NOT success)
  {
    scanned = scanf("%i.%i%*c", &amt1, &amt2);

    /* validate and verify amount */
    if (scanned >= 1)
    {
      printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", amt1, amt2);
      scanf("%c%*c", &yn);
      if (yn == '\0' OR yn == 'Y' OR yn == 'y')
    success = TRUE;
    }
  }
  return (100*amt1 + amt2);
}

最佳答案

正如@MitchWheat在上面的一条评论中已经提到的,当您打印出float时,它可能会被取整,而当您计算int时,它只会被截断。使用round函数解决这个问题。即,i_amt = round(100 * amt);,它将以与float被舍入相同的方式舍入数字。

10-08 05:11