我无法理解为什么下面的代码与值4.2
无法正常工作。我学会了使用4.2
实际上不是第四点的调试器;而是浮点值4.2变为4.19999981
为了弥补这一点,我刚刚在第18行添加了change = change + 0.00001;
。
为什么我必须这样做?为什么这是浮点整数的工作方式?
#include <stdio.h>
#include <cs50.h>
float change;
int coinTotal;
int main(void)
{
do {
// Prompting the user to give the change amount
printf("Enter change: ");
// Getting a float from the user
change = get_float();
}
while (change < 0);
change = change + 0.00001;
// Subtracting quarters from the change given
for (int i = 0; change >= 0.25; i++)
{
change = change - 0.25;
coinTotal++;
}
// Subtracting nickels from the remaining change
for(int i = 0; change >= 0.1; i++)
{
change = change - 0.1;
coinTotal++;
}
// Subtracting dimes from the remaining change
for(int i = 0; change >= 0.05; i++)
{
change = change - 0.05;
coinTotal++;
}
// Subtracting pennies from the remaining change
for(int i = 0; change >= 0.01; i++)
{
change = change - 0.01;
coinTotal++;
}
// Printing total coins used
printf("%i\n", coinTotal);
}
答案 0 :(得分:1)
正如你所发现的那样。在计算机上将有理数表示为浮点值是不可能的,因为机器将它存储在一些固定大小的位中。
最常见的标准是IEEE 754 Check here
最常见的是,您将使用单精度浮点数(总共32位)。符号表示为1位,指数为8位,尾数为23位
表示如下x=S*M*B^E
其中:
S - 符号(-1或1)
M - 尾数(归一化分数)
B - Base(此处为2)
E - 指数(8位 - > -128,127或0,255,取决于标准中的定义)
这个分数是(M)导致问题的准确表示值。在给定有限的位数时,您需要表示某个近似(您只能准确地表示可以通过求和,1 / 4,1 / 8 ......的总和来组合的值) 通常32位允许您在分数中获得大约6个位置的精度。
您可以使用64位(双精度)来获得更大的范围和更好的精度。
答案 1 :(得分:1)
Typically float
可以代表约2 32 不同的值完全。使用float
,4.2不是其中之一。相反,当OP报告时,该值为约 4.19999981。
使用小数资金很棘手。 float
很少是可接受的金钱类型。 This详细介绍了一些替代方案,例如base-10 FP,double
,整数和自定义类型。
如果代码保留某些FP类型,change >= 0.1
和其他比较,则需要更改为change >= (0.01 - 0.005)
等。比较需要容忍小于或大于0.01的倍数的值。
答案 2 :(得分:0)
将程序中的每个数字放大100倍,使用math.h roundf函数,并在将值打印到屏幕时将结果除以100。