10**-6 vs 0.000001 - just a representation or?

14,038

Solution 1

To test if two float values are exactly equal, just use ==:

>>> 0.000001 == 10**-6
True

You may be confusing representation with the value. Python formats a float, when echoed in the interpreter, with the repr() function, and it represents the value by formatting with the g notation; this notation switches to using the scientific representation (e formatting) when the exponent gets large enough. repr() is effectively the same as format(value, '.16g').

You can format the numbers manually:

>>> format(10**-6, '.53f')
'0.00000099999999999999995474811182588625868561393872369'
>>> format(0.000001, '.53f')
'0.00000099999999999999995474811182588625868561393872369'

where .53f formats the value with up to 53 decimal numbers, a semi-arbitrary number based on the limits of what a floating point value can encode.

And indeed, both values are exactly the same. This was not a given; a float calculation can easily introduce small errors as float numbers are but approximations with binary fractions, after all.

Solution 2

FWIW in order to convince yourself, you might use the marshal module to see a binary representation of the object:

>>> import marshal
>>> marshal.dumps(10**-6)
'g\x8d\xed\xb5\xa0\xf7\xc6\xb0>'
>>> marshal.dumps(0.000001)
'g\x8d\xed\xb5\xa0\xf7\xc6\xb0>'

As you can see, both values have the same binary representation.

Solution 3

There is never "exactness" with floating point so whilst the numbers are logically the same you cannot guarantee you will get 0.0 when you subtract them, but might get a very small number (e.g. 1e-21) due to a rounding error.

With regards to how it prints, that is a formatting issue.

Share:
14,038
Richard Knop
Author by

Richard Knop

I'm a software engineer mostly working on backend from 2011. I have used various languages but has been mostly been writing Go code since 2014. In addition, I have been involved in lot of infra work and have experience with various public cloud platforms, Kubernetes, Terraform etc. For databases I have used lot of Postgres and MySQL but also Redis and other key value or document databases. Check some of my open source projects: https://github.com/RichardKnop/machinery https://github.com/RichardKnop/go-oauth2-server https://github.com/RichardKnop

Updated on June 28, 2022

Comments

  • Richard Knop
    Richard Knop almost 2 years

    In Python when I raise 10 to the minus sixth power:

    >>> 10**-6
    1e-06
    

    It will display 1e-06.

    Is there a noticable difference between writing 10**-6 and 0.000001 as displayed in the interpreter? Or is it just representation / formatting difference.

  • Richard Knop
    Richard Knop over 9 years
    Yes I know. What I meant is if 10**-6 returns a float, the same way as when I type 0.000001. I was just wondering about formatting 1e-06 in the console and if it has any significance.
  • Richard Knop
    Richard Knop over 9 years
    Yes. Thank you. I was just not sure if the representation in the interpreter means 1e-06 is just formatting / representation thing or there is some difference in data types and some conversion going on.
  • Quentin THEURET
    Quentin THEURET over 9 years
    You can also use the module Decimal of Python to works with Decimal fixed point and floating point objects.
  • Richard Knop
    Richard Knop over 9 years
    Thanks. I guess this wasn't a clever question, I got -1 :(. I edited my question to make more sense, removing the calculation which wasn't the point of my question really.
  • wim
    wim over 9 years
    struct.pack should do the job too
  • Martijn Pieters
    Martijn Pieters over 9 years
    @RichardKnop: And with your question changed, I got a -1 too; I updated my question slightly to address your new version better.