1
my_number = 42379943902701922
print(my_number * 10**-18)

Expected output: 0.042379943902701922

Actual output: 0.04237994390270192

Actual output is missing one 2 at the end. Why is that so and how can I arrive at the expected output?

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
Exa
  • 466
  • 3
  • 16
  • 4
    Floating point doesn't have enough bits to keep that digit. – Barmar Oct 12 '22 at 14:23
  • 2
    see https://docs.python.org/3/tutorial/floatingpoint.html ... as an alternative, use `Decimal` https://docs.python.org/3/library/decimal.html – Anentropic Oct 12 '22 at 14:24
  • 1
    Do the answers to this [question](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) help at all? – quamrana Oct 12 '22 at 14:26
  • `print(f'{my_number * 10**-18:.18f}')` - it gives me 18th place but it has value `3` instead of `2` because float can't keep the exact value. Using `.60f` I get `0.042379943902701923408304907070487388409674167633056640625000` – furas Oct 12 '22 at 14:32

3 Answers3

3

In addition to Decimal, you can use the BigFloat library for precise decimal numbers. Example:

from bigfloat import *

precise_number =  BigFloat('0.042379943902701922', precision(18))

Alternatively, to do the calculation:

with precision(18) + RoundTowardZero:
    print(BigFloat.exact(my_number * 10**-18))
voiarn
  • 547
  • 6
  • 13
2

By default, Python interprets any number that includes a decimal point as a double-precision floating point number. However, you can bypass that by using the decimal module, which provides support for correctly rounded decimal floating point arithmetic.

Example:

getcontext().prec = 28
Decimal(1) / Decimal(7)

Output:

Decimal('0.1428571428571428571428571429')
  • 4
    I think better example could be `Decimal(42379943902701922) / Decimal(10**18)` like in OP question. – furas Oct 12 '22 at 14:37
0

Thats how its getting printed in console/terminal. You can convert to string while printing if you want to see all the digits

# How it gets printed
>>> print(my_number * 10**-18)
0.04237994390270192

# How its stored
>>> my_number
42379943902701922

# How to print all the digits
>>> print(str(my_number))
42379943902701922

# Or with repr
>>> repr(my_number)
'42379943902701922'

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45