0

Suppose I have the following code:

0.7 / 100

I would expect to get 0.007 but instead I am getting 0.006999999. I know this is a float precision error but how do I get the expected value?

I tried:

Decimal(0.7 / 100)
Decimal(0.7)/int(100)

But can’t seem to get it to work. Tried searching but can’t seem to phrase it right to get a good result.

khelwood
  • 55,782
  • 14
  • 81
  • 108
Denis
  • 11,796
  • 16
  • 88
  • 150
  • What about `round(0.7/100, 3)`? –  Mar 17 '22 at 20:40
  • `0.7` cannot be represented precisely as a float, because it is not exactly expressible in binary. With Decimal you would use `Decimal('0.7')/100`. – khelwood Mar 17 '22 at 20:41
  • Does this answer your question? [Python float point precision](https://stackoverflow.com/questions/65820552/python-float-point-precision) – John Y Mar 17 '22 at 20:49
  • This question has been asked so many times. I'm using [this](https://stackoverflow.com/questions/65820552/python-float-point-precision) as the "target" of my close vote even though that question is itself marked as a duplicate. The link I provided more specifically addresses how to get exact decimals in Python (and points to other references). – John Y Mar 17 '22 at 20:52

2 Answers2

3
from decimal import Decimal

>>> number = Decimal('0.7') / 100
>>> float(number)
0.007
Jonatrios
  • 424
  • 2
  • 5
  • After which, `number == float(number)` returns `False`. They're not actually getting the decimal value `0.007`, they're getting a binary float whose display happens to _round_ to 0.007. Which may or may not be good enough for what they really want. Can't guess from here. Do they want the exact result, or an illusion? :-) – Tim Peters Mar 17 '22 at 20:53
  • @TimPeters that's what you face when working with floating point numbers. Decimal class is more accurate that float built-in, but is memory inefficient. As always, it depends on what you need and the requirements implementation. – Jonatrios Mar 17 '22 at 21:02
  • And I was emphasizing that the OP's actual requirements were not made clear. What you suggested may, or may not, satisfy their actual requirements. As an aside, no, the decimal module is not "more accurate" in general. It's still floating-point, and suffers from _almost_ all the same inherent limitations of binary floating point (like the need to throw away information to rounding, the possibility for catastrophic cancellation, and so on). What it _doesn't_ suffer from is systematic representation error for values expressed in base 10 notation. – Tim Peters Mar 17 '22 at 21:11
  • You are totally right man!! :) – Jonatrios Mar 17 '22 at 21:38
0

0.7 is a floating point literal, so creates a binary floating point value regardless of what you do with it.

The decimal module can create decimal values exactly, but you need to pass the constructor a string instead, or build the result out of other exact values:

For example,

>>> import decimal
>>> decimal.Decimal("0.7") / 100
Decimal('0.007')
>>> decimal.Decimal(7) / 1000
Decimal('0.007')
Tim Peters
  • 67,464
  • 13
  • 126
  • 132