Thursday, August 11, 2022

[FIXED] How do I keep the precision in my Python function?

Issue

All,

I am working on a simple function which accepts a value and calculates the minimum number of coins to distribute based on the value. I've been using 1.20 as my amount. Thus, I should get back 6 coins - 2 quarters and 2 dimes. For simplicity sake, I am only showing the quarters portion of the code. When I run my sample code below, the precision for the operation amount = amount - quarters is correct through the first two iterations, however, by the third, the amount changes to 0.44999999999999996.

  • 1st iteration: 0.95
  • 2nd iteration: 0.7
  • 3rd iteration: 0.44999999999999996

Do you know why this happening and how I fix this issue? I've tried using decimal.Decimal and changing the precision. I don't want to fix only the formatting but would like to fix the actual amount as that is crucial to how many coins are counted.

#amount for testing
amount = 1.20

#coins
quarter = 0.25

def min_coins(amount):
    count_quarter = 0
    while amount >= quarter:
        amount = amount - quarter
        print(amount)
        count_quarter += 1

min_coins(amount)

Solution

As John Gordon notes, for monetary applications, you don't want to use floating point at all. Either use the decimal.Decimal module to perform decimal accurate calculations, or perform your math with int pennies, instead of float dollars; if the API must accept float dollars, convert the values on entry, and convert back on return. For your code, the int pennies approach would look like:

#amount for testing
amount = 1.20

#coins
quarter = 25

def min_coins(amount):
    amount = round(amount * 100)  # Convert from float dollars to int pennies
    count_quarter = 0
    while amount >= quarter:
        amount -= quarter
        print(amount)  # Or print('{:.2f}'.format(amount / 100)) if necessary
        count_quarter += 1

min_coins(amount)


Answered By - ShadowRanger
Answer Checked By - Terry (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.