C - 浮点数不精确,如何锁定小数点后位置进行计算?

C - Float Imprecision, How to lock the decimal places for calculations?

提问人:Will Felipe 提问时间:9/10/2021 最后编辑:Eric PostpischilWill Felipe 更新时间:9/14/2021 访问量:209

问:

我当时在C语言中做了一个小程序来测试浮点数:程序本身很简单,我只想根据用户的输入,返回多少,他的数字有多少。Dollar(s), Quarter(s)... etc

//------------------------------> First Part: All the necessary Variables <-----------------------------
 
int main (void)
{
    //Getting the user Input
    float number = get_float("Number: ");
   
    //Checking if is a positive number
    if (number < 0)
    {
        printf("A positive number, Please: ");
    }

    //Declaring my Constant/Temporary variables.
    float coinValues[] = {1.00, 0.25, 0.10, 0.5, 0.01};
    char  *coinNames[] = {"Dollar(s): ", "Quarter(s): ", "Dime(s): ", "Nickel(s): ", "Penny(ies): "};
    int   i            = 0;
    int   tmp          = 0;
    
//-----------------------------------> Second Part: The code Itself <-----------------------------------

    //Checking/Printing the necessary coins.
    while (number > 0)
    {
        //Until the loop stops, check if the number can be divided by the CoinValue.
        if (number >= coinValues[i])
        {
            //Print the current Coin Name from the divided value.
            printf("%s", coinNames[i]);
            //Check if the Current Number still contains Coin Values inside of it, if True counts one in your "Coin Score".
            while (number >= coinValues[i])
            {
                number -= coinValues[i];
                tmp++;
            }
            //Print the Current "Coin Score", then resets TMP.
            printf("%i\n", tmp);
            tmp = 0;

        }
        else
        {   
            //Updating the Coin value
            i++;
        }

    }
    
}

只要我使用整数,我的程序运行得很好,但是当我将此代码转换为浮点数时,值开始在 Int 变量 tmp 中返回非预期结果。(Dime(s), Nickel(s), and Penny(ies))

2.6 这样的数字的预期结果是 2 美元2 个季度和 1 角钱,但有时,程序不会使用一角钱,而是将它们全部跳过并使用进行操作,但是,困扰我的是程序总是返回没有任何值的 AWL=+,然后程序永远冻结。

考虑到我唯一的想法是我正在“遭受”浮动不精确,我不知道如何解决它,那么任何人都可以帮助我吗?

附言。在传递之前,程序需要始终返回每个硬币的最大值

c 数学 数字 浮点精度

评论

1赞 Some programmer dude 9/10/2021
自然的开始方式是使用精度更高的类型,例如 .在那之后,这实际上取决于您的要求,以及您的计算真正需要的精确程度。double
9赞 Some programmer dude 9/10/2021
至于钱的问题,不要使用浮点计算。将所有货币转换为最小的货币单位(例如美元,使用美分),然后您可以使用整数算术,并且不会失去精度或出现舍入错误。因此,以 2.60 美元为例,这将是 260 美分。
1赞 Some programmer dude 9/10/2021
最后,关于硬币兑换问题:我建议你考虑一下除法。例如,什么是(截断为整数)?什么是(再次截断为整数)?260 / 10060 / 25
1赞 John Bode 9/10/2021
像 和 这样的值不能精确地用二进制浮点表示,任何使用它们的计算都会有一些错误。就像社民党所说,对于货币使用,整数缩放到最小单位(对于美元,美分(1/100美元)或密耳(1/1000美元))。0.10.01
0赞 Robert Dodier 9/10/2021
除了使用整数外,还可以使用精确十进制或有理类型。网络搜索应该会找到一些资源。

答:

4赞 Eric Postpischil 9/10/2021 #1

浮点运算旨在近似于实数算术。IEEE 754-2008 说:“浮点运算是实数算术的系统近似......”因此,无法在二进制浮点数中“锁定”十进制数字。它旨在用于需要近似值的地方,例如建模物理场。这甚至包括一些金融应用,例如期权评估。虽然浮点运算在某些情况下可用于精确计算,但这些需要特别小心,并且通常只在特殊情况下使用。

因此,关于如何锁定小数位的问题的答案是,使用二进制浮点没有很好的方法可以做到这一点。尝试这样做通常只会产生与整数算术相同的效果,但效率较低且代码难度更大。因此,请使用整数算术,并根据所需的最小货币单位(例如一分钱)缩放金额。