-1

To make things short, I have scientific notation 4.534524725984957e+16 and I am trying to get the suppression..

The correct number here is 45345247259849570...but python keeps returning wrong numbers like 45345247259849568...any ideas?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • What is a suppression? – Mad Physicist Mar 21 '23 at 16:01
  • 2
    How are you trying to get it? Are you aware of how finite-precision IEEE-754 doubles are stored? – Mad Physicist Mar 21 '23 at 16:02
  • Are you looking for floating point formatting? Use `f"{mynumber:.6e}"` or similar. See https://docs.python.org/3/library/string.html#format-specification-mini-language (scroll down until you find "float and Decimal values"). – 9769953 Mar 21 '23 at 16:06
  • 3
    "wrong numbers" is not true. Search around for "floating point numbers precision". Your computer's CPU has a precision limit. – 9769953 Mar 21 '23 at 16:07

2 Answers2

1

Floating-point literals give the appearance of more precision than the float type actually provides. Python does its best to map such a literal to value that's close to what you want.

>>> float(45345247259849570)
4.534524725984957e+16
>>> float(45345247259849568)
4.534524725984957e+16
>>> float(45345247259849570) == float(45345247259849568)
True
>>> float(45345247259849570) == 4.534524725984957e+16
True
chepner
  • 497,756
  • 71
  • 530
  • 681
0

Recall that a Python float is a C double under the hood. It's stored in binary scientific notation.

In binary, the 56-bit integer 45345247259849570 is represented as 10100001000110010100001100011011001011001111001101100010. Or in scientific notation, 1.0100001000110010100001100011011001011001111001101100010 × 255. (I've bolded the least-significant digits bolded for comparison.)

The thing is, only 53 significant digits can be stored. So your number gets rounded down to 1.0100001000110010100001100011011001011001111001101100 × 255, which works out to 45345247259849568 in decimal.

If you're not willing to accept this rounding error, the solution is to use the proper data type to store your numbers.

The built-in int (or long if you're still using Python 2.x) can exactly store any integer (whole number) that can fit in a process's memory. Of course, it doesn't work if you have digits to the right of the decimal point.

decimal.Decimal is a floating-point type that stores 28 decimal digits by default. It's great for financial calculations, in which “$0.01” means exactly 1/100 of a dollar, and not 0.01000000000000000020816681711721685132943093776702880859375.

>>> from decimal import Decimal
>>> Decimal('4.534524725984957e+16')
Decimal('4.534524725984957E+16')

However, non-decimal fractions like 1/3 are still only approximated.

>>> Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
>>> _ * 3
Decimal('0.9999999999999999999999999999')

fractions.Fraction will exactly store any rational number as a numerator/denominator pair.

>>> from fractions import Fraction
>>> Fraction('4.534524725984957e+16')
Fraction(45345247259849570, 1)
dan04
  • 87,747
  • 23
  • 163
  • 198