C++ floating point accuracy in while loops

前端 未结 4 440
暖寄归人
暖寄归人 2021-01-23 04:10

I am trying to count the amount of dollar and coin denominations in a grand total by using a series of while loops. When I get down to the coins however, I am off by a penny. Wh

相关标签:
4条回答
  • 2021-01-23 04:47

    Don't use floating point in cases where you need exact values. 99.95 can't be exactly represented in a float or double, a bit like 1/3 can't be exactly represented using a finite number of normal decimal digits.

    As Doug T. suggested, you can use an integer to hold the number of pennies. When the user types 123.45, read it as two integers, and then store it as 12345 pennies, not as 123.45 dollars.

    In this case, you can also try to change your last while (amount >= .01) to something like while (amount >= .005). It's not a solution that can be generally recommended, and if this is a real-life bank application you really should avoid it, but it will help against at least some of the errors.

    0 讨论(0)
  • 2021-01-23 04:51

    You should be using fixed-point values in this case, not floating-point.

    Although people think of money in terms of dollars, which aren't exact, money is measured in cents, which are exact. Just count the number of cents, divide by 100 to get the dollar amount, and take the modulus to get the cent amount. Floating-point is not the proper tool in this case.

    0 讨论(0)
  • 2021-01-23 04:54

    Here's the fixed code, I used TJD's advice and instead of using .01 i used .0099 instead. For my problem that seems to work, thanks guys!

        #include <iostream>
    using namespace std;
    
    int main()
    
    {
       float amount;
       cout<<"enter amount" << endl;
       cin>>amount;
       int pennies=0, nickels=0, dimes=0, quarters=0, ones=0, fives=0, 
    tens=0, 
    twenties=0, fifties=0, hundreds=0;
       float p = .0099, n = .0499, d = .099, q = .2499;   
       while (amount >= 100) 
       {
          hundreds = hundreds +1;
          amount = amount - 100;
    
       }
       while (amount >= 50)
       {
          fifties = fifties +1;
          amount = amount - 50;
    
       }
       while (amount >= 20)
       {
          twenties = twenties +1;
          amount = amount - 20;
    
       }
       while (amount >= 10)
       {
          tens = tens +1;
          amount = amount - 10;
    
       }
       while (amount >= 5)
       {
          fives = fives +1;
          amount = amount - 5;
    
       }
       while (amount >= 1)
       {
          ones = ones +1;
          amount = amount - 1;
    
       }
       while (amount >= q)
       {
          quarters = quarters +1;
          amount = amount - q;
    
       }
       while (amount >= d)
       {
          dimes = dimes +1;
          amount = amount - d;
    
       }
       while (amount >= n)
       {
          nickels = nickels +1;
          amount = amount - n;
    
       }
       while (amount >= p)
       {
          pennies = pennies +1;
          amount = amount - p;
    
       }
    
    
       cout<<endl<<"pennies:"<< pennies;
       cout<<endl<<"nickels:"<<nickels;
       cout<<endl<<"dimes:"<<dimes;
       cout<<endl<<"quarters:"<<quarters;
       cout<<endl<<"ones:"<<ones;
       cout<<endl<<"fives:"<<fives;
       cout<<endl<<"tens:"<<tens;
       cout<<endl<<"twenties:"<<twenties;
       cout<<endl<<"fifties:"<<fifties;
       cout<<endl<<"hundreds:"<<hundreds<<endl;
    
    
    
    
    
    
    
    return 0;
    }
    
    0 讨论(0)
  • 2021-01-23 05:01

    Binary floating point numbers cannot, in general, represent fractional decimal values, even if the total number of decimals is small. For example, 0.1 cannot be represented exactly.

    To deal with exact values different approaches exist which all amount to using a different base than 2. Depending on tge specific needs the approaches are more or less involved. The easieast approach for your case is to use a fixed precision instead of a variable precision. To compute with fixed precision you'd just use an integer which represents the value you actually want multiplied by a suitable power of 10. Depending on the amount of computations you do you can either package the logic into a class or distribute it throughout the code. In a "real" application I'd package it into a class, in an assignment (homework, interview, etc.) I'd probably just apply the logic directly to an int.

    0 讨论(0)
提交回复
热议问题