与C中的浮点值略有混淆。(cs50 pset1 greedy.c)

时间:2017-07-22 00:54:56

标签: c floating-point precision cs50 greedy

我无法理解为什么下面的代码与值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);
}

3 个答案:

答案 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。