While循环会忽略比较两个浮点变量的布尔表达式

时间:2018-07-09 18:21:33

标签: c cs50

编辑:
我解决了这个问题,首先将浮点值乘以100,然后使用roundf()函数将其舍入,然后将其强制转换为要存储在整数变量中的整数。我从那里开始使用整数值进行其余操作,一切正常。即使@JacobBoertjes提供的解决方案确实有效,但我的任务还是要求我使用get_float()库中的cs50.h,所以我没有实现它。这是最终的代码:

// Get user input as a positive float value
float f_change;
do {
    printf("Change owed: ");
    f_change = get_float();
} while(f_change < 0);

// Round & cast
int int_change = (int) roundf(f_change * 100);

我的程序接受一定数量的货币,例如$ 4.20,并找出可以表示该值的最小硬币数量。例如,从程序中以$ 4.20作为输入的期望输出将是:16个季度($ 4.00),2个1角硬币($ 0.20)。

我的程序成功计算了季度数,但未能成功在角钱上工作。失败的原因是代码中的第二个 for循环 0.10> = 0.10 的计算结果不为true,因此循环的最后一次迭代永远不会发生。我究竟做错了什么?

这是代码。我提供了测试打印语句,并将其输出写为注释。

#include <stdio.h>
#include <cs50.h>

int main(void) {

  // Fake user input
  float owed_coin = 4.2f;

  // Initialize coin variables
  int coin_count = 0;

  float quarters = 0.25f,
        dimes = 0.10f;

  // Calculate quarters
  while(owed_coin >= quarters) {
    owed_coin -= quarters;
    coin_count += 1;
  }
  printf("owed_coin: %.2f\ncoin_count: %d\n\n", owed_coin, coin_count);
  // Prints  owed_coin: 0.20
  //         coin_count: 16

  // Calculate dimes
  while(owed_coin >= dimes) {
    owed_coin -= dimes;
    coin_count += 1;
  }
  printf("owed_coin: %.2f\ncoin_count: %d\n\n", owed_coin, coin_count);
  // Prints  owed_coin: 0.10
  //         coin_count: 17

}

1 个答案:

答案 0 :(得分:1)

浮点比较通常不是一个好主意,因为浮点数经常变得不精确,因此将不完全相等。如@bruceg所述,一个好的解决方案是将您的货币价值保持为美分,从而避免使用浮点数。

您可以将float owed_coin = 4.2f;替换为int owed_coin = 420;

关于收集用户输入此号码的建议,这是我对scanf的建议

int n1, n2;

printf("Please enter amount:");
scanf("%d.%2d", &n1, &n2);

owed_coin = n1*100 + n2;

另一种解决方案使您可以将变量保持为浮点数,并且只需比较两者之间的很小差异即可。可以在这里找到:What's wrong with using == to compare floats in Java?

它使用Java Math库,但是类似的解决方案在C语言中可能看起来像这样:

while((owed_coin - dimes) >= -0.001) {
    owed_coin -= dimes;
    coin_count += 1;
}

如果您想更多地了解为什么浮点数会遭受小的无利可图,请查看以下内容:https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems