5

Why is 10**5 equal to 1e5 but 10**50 is not equal to 1e50 in Python?

Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 10**5 == 1e5
True
>>> 10**50 == 1e50
False

It's true up to 10**22. Then it's false:

>>> 10**22 == 1e22
True
>>> 10**23 == 1e23
False
Boann
  • 48,794
  • 16
  • 117
  • 146
Tomasz Sikora
  • 1,649
  • 3
  • 19
  • 30
  • 2
    `1e23` is a `float`, so the mathematical inaccuracy is for the same fundamental reason as every other mathematical inaccuracy with floating-point. – Karl Knechtel Jul 31 '21 at 19:05
  • I agree -- OP probably didn't think to check the type (if they did, the significance of it being float may be lost on them; that's all the canonical addresses), and the behavior about when the cutoff occurs is Python-specific. – ggorlen Jul 31 '21 at 19:07
  • 1
    Maybe I'm too tired, but if there is a difference due to limited precision of floating point numbers, why this difference cannot be displayed as a floating point number? `(10**50 - 1e50) == 0.0` is True – VPfB Jul 31 '21 at 19:51
  • 1
    If you are doing computations with high numbers like this I strongly recommand to use `numpy.isclose()` or `numpy.allclose()` for arrays to check if 2 numbers are equals within a tolerance. – politinsa Jul 31 '21 at 20:38
  • @VPfB because the comparison coerces both sides to a float first. Explicitly converting to `decimal.Decimal` helps. – o11c Jul 31 '21 at 20:42
  • @o11c Sir could you elaborate your comment a bit (how does "comparison coerces both sides to a float first" cause `(10**50 - 1e50) == 0.0)` to be True)? or provide a reference link if it is possible. – S.B Jul 31 '21 at 22:23
  • @SorousHBakhtiary I'm not sure it's documented anymore; it used to be documented using the out-of-line `coerce` function. – o11c Aug 01 '21 at 00:06
  • 2
    @SorousHBakhtiary Could be this the reference you are lookig for? https://docs.python.org/3/reference/expressions.html#arithmetic-conversions – VPfB Aug 01 '21 at 06:40
  • @VPfB Exactly ! thank you. – S.B Aug 01 '21 at 09:09
  • @o11c So in fact **arithmetic operator** causes this conversion not the **comparison operator**, that's the reason why `(10**50 - 1e50) == 0.0` is True, They both become float first, then the result of subtraction is `0.0`. – S.B Aug 01 '21 at 09:11
  • @SorousHBakhtiary Er, right. My bad. – o11c Aug 01 '21 at 14:06
  • @o11c If you force the coercion the other way: `10**50 - int(1e50)` the result is `-7629769841091887003294964970946560`. – Mark Tolonen Aug 01 '21 at 15:39

1 Answers1

13

Python 3 supports big integers and uses them whenever it can. 10**50 is a calculation on integers and produces the exact number ten to the fiftieth power. On the other hand, scientific notation always uses floating point, so 1e50 is a floating-point value that's approximately equal to ten to the fiftieth power.

>>> type(10 ** 50)
<class 'int'>
>>> type(1e50)
<class 'float'>
Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • Thank you for quick answer! I wanted to delete this question as I just checked print(int(1e78)) which was not actually a number with 1 and 78 zeroes because of float precision. – Tomasz Sikora Jul 31 '21 at 19:07
  • 7
    I strongly recommend against deleting the question. It's a fair question that could easily help someone else. If you think you have more insight into the answer, then by all means post a second answer with your findings. The more, the merrier! – Silvio Mayolo Jul 31 '21 at 19:11
  • For reference, on my machine: `1e23 == 10**23 - 8388608` – wjandrea Jul 31 '21 at 20:39
  • 2
    Another note: `10.0**50` equals `1e50` (because both floats) – VPfB Aug 01 '21 at 06:47
  • *"Python 3 supports big integers"* - As does Python 2. – Kelly Bundy Aug 10 '21 at 12:25