【问题标题】:C - Float Imprecision, How to lock the decimal places for calculations?C - Float Imprecision,如何锁定计算的小数位?
【发布时间】:2021-11-06 07:46:42
【问题描述】:

我正在做一个小程序来测试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++;
        }

    }
    
}

只要我使用 Integers,我的程序运行得非常好,但是当我将此代码转换为 Floats(Dime(s), Nickel(s), and Penny(ies)) 开始返回 非预期 结果,导致 Int 变量 tmp

2.6 等数字的预期结果将是 2 Dollars2 Quartersand 1 Dime,但有时,程序不使用 Dime(s),而是将它们全部跳过并使用 Nickel(s) 进行操作,但是,有什么困扰着我是程序总是返回 AWL=+ 没有任何价值,然后程序永远冻结。

考虑到我唯一的想法是我正在“遭受”Float Imprecision 的困扰,而且我不知道如何解决它,所以任何人都可以帮助我吗?

Ps.程序需要在传递前总是返回每个硬币最大值

【问题讨论】:

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

标签: c math numbers precision floating-accuracy


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2011-07-06
    • 2018-01-25
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多