# Precision of decimals in Python

## Question:

I don’t mean precision as in how many numbers are displayed after the decimal. I mean precision as in the decimal I am trying to use in this pictograph function keeps coming up one tenth shy of what it should be. I have tried using multiple different strategies including importing the decimal module. Here is the function I am trying to use.

``````values = [('tens', 10), ('fives', 5), ('ones', 1), ('tenths', 0.1)]

def get_digits(num):
num = int(num * 10)
num = float(num) / 10

output_dict = {}
for place, value in values:
output_dict[place] = int(num // value)
num = num % value

return output_dict
``````

using `get_digits(277.9)`, yields `{'tens': 27, 'ones': 2, 'tenths': 8, 'fives': 1}`

I need for it to say `{'tens': 27, 'ones': 2, 'tenths': 9, 'fives': 1}`

Fixing it by adding 1 to the tenths after the dictionary is populated does not work, because not every decimal comes out imprecisely.

`get_digits(277.6)` returns `{'fives': 1, 'tenths': 6, 'tens': 27, 'ones': 2}`

I’ve been scouring the forums for an answer, but nothing quite gets it. Any assistance would be greatly appreciated.

As I tried to explain in comments, the problem is that you’re using floating point numbers.

The issue is that `277.9` is not actually stored as `277.9`, but rather something “very close”:

``````print('%.40f' % a)
277.8999999999999772626324556767940521240234
``````

The solution isn’t to use some arbitrary heuristic to tell whether the math is slightly off and try to correct for it. We know the math is slightly off — that’s the gift and curse given to us by floating point.

The real solution is to use fixed point math, for example, with Python’s `decimal` module.

Edit

``````from decimal import Decimal

values = [
('tens',   Decimal(10)),
('fives',  Decimal(5)),
('ones',   Decimal(1)),
('tenths', Decimal('0.1'))
]

def get_digits(num):
output_dict = {}
for place, value in values:
output_dict[place] = int(num // value)  # Cast from Decimal to int
num = num % value
return output_dict

num = Decimal('277.9')
print(get_digits(num))
# {'tens': 27, 'ones': 2, 'tenths': 9, 'fives': 1}

num = Decimal('277.6')
print(get_digits(num))
#{'tens': 27, 'ones': 2, 'tenths': 6, 'fives': 1}
``````

The above code is very similar to yours, but uses Python’s decimal module. No heuristic check is needed. The code just works, because decimals are represented accurately.

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.