Binary Decimals in Python

Discussion in 'Python' started by aditya, Mar 30, 2010.

  1. aditya

    aditya Guest

    To get the decimal representation of a binary number, I can just do
    this:

    int('11',2) # returns 3

    But decimal binary numbers throw a ValueError:

    int('1.1',2) # should return 1.5, throws error instead.

    Is this by design? It seems to me that this is not the correct
    behavior.

    - Aditya
     
    aditya, Mar 30, 2010
    #1
    1. Advertisements

  2. So, why should int('1.1', 2) throw an error when int('1.1') doesn't?

    Regards,
    Pat
     
    Patrick Maupin, Mar 30, 2010
    #2
    1. Advertisements

  3. aditya

    Grant Olson Guest

    Well technically that would be a 'radix point', not a decimal point.

    But I think the problem is that computers don't store fractional values
    that way internally. They either use floating or fixed point math. You
    would never look at raw binary data on a computer and see something like
    '1010.1010', and no one would write it that way, and no language (that I
    know of) would accept that as a valid value if you did something like "x
    = 0b1010.1010"

    So in that sense, it might not be an intentional oversight, but it's not
    a very practical or useful feature.
     
    Grant Olson, Mar 30, 2010
    #3
  4. Because int stands for integer and 1.1 is not an integer. You get the
    same error if you try doing int('1.1')
     
    Benjamin Kaplan, Mar 30, 2010
    #4
  5. The int() constructor returns integers.
    So, look to float() for non-integral values.
    Binary representation isn't supported yet,
    but we do have hex:
    1.5


    Raymond
     
    Raymond Hettinger, Mar 30, 2010
    #5
  6. aditya

    Grant Olson Guest

    Doh!

    Well the problem is that int's are integers. So yeah, you can't even do
    that with normal value "int ('2.1')" will also throw an error. And
    floats don't support radix conversion, because no-one really writes
    numbers that way. (At least computer programmers...)
     
    Grant Olson, Mar 30, 2010
    #6
  7. aditya

    MRAB Guest

    int() returns an integer (hence the name!), so it should never return a
    float anyway.

    What you want is for float() to accept a base, but that is rarely
    needed.
     
    MRAB, Mar 30, 2010
    #7
  8. aditya

    aditya Guest

    That makes sense. The closest thing I've found is this question on
    StackOverflow: http://stackoverflow.com/questions/1592158/python-convert-hex-to-float

    It seems to me that adding a conversion feature to floats would be a
    lot more intuitive.
     
    aditya, Mar 30, 2010
    #8
  9. aditya

    aditya Guest

    That looks very elegant, thanks!
     
    aditya, Mar 30, 2010
    #9
  10. Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ValueError: invalid literal for int() with base 10: '1.1'


    int('1.1', 2) shouldn't return 1.5 because 1.5 isn't an integer.


    The obvious question is, why doesn't float('1.1', 2) work? The answer is
    that Python doesn't support floats in any base except 10. It's not
    something needed very often, and it's harder to get right than it might
    seem.
     
    Steven D'Aprano, Mar 30, 2010
    #10
  11. aditya

    Mensanator Guest

    It is supported in the gmpy module.
    Help on built-in function mpf in module gmpy:

    mpf(...)
    mpf(n): builds an mpf object with a numeric value n (n may be any
    Python number, or an mpz, mpq, or mpf object) and a
    default
    precision (in bits) depending on the nature of n
    mpf(n,bits=0): as above, but with the specified number of bits (0
    means to use default precision, as above)
    mpf(s,bits=0,base=10): builds an mpf object from a string s made
    up of
    digits in the given base, possibly with fraction-part
    (with
    period as a separator) and/or exponent-part (with exponent
    marker 'e' for base<=10, else '@'). If base=256, s must be
    a gmpy.mpf portable binary representation as built by the
    function gmpy.fbinary (and the .binary method of mpf
    objects).
    The resulting mpf object is built with a default precision
    (in
    bits) if bits is 0 or absent, else with the specified
    number
    of bits.
     
    Mensanator, Mar 30, 2010
    #11
  12. Until you try running your program on a machine that represents floats
    using a radix other than 2,4, or 16.

    ;)

    And it works for NaN and Inf too!

    It would have been nice to have had that 5-6 years ago when I had to
    write my own pickle/unpickle methods for floating point values so that
    inf and nan were portable between Windows and Linux.
     
    Grant Edwards, Mar 30, 2010
    #12
  13. aditya

    John Nagle Guest

    Hex floats are useful because you can get a string representation
    of the exact value of a binary floating point number. It should
    always be the case that

    float.fromhex(float.hex(x)) == x

    That's not always true of decimal representations, due to rounding problems.

    Long discussion of this here: "http://bugs.python.org/issue1580"


    John Nagle
     
    John Nagle, Mar 30, 2010
    #13
  14. aditya

    MRAB Guest

    Floats have a limited length, unlike ints which are virtually unlimited.
     
    MRAB, Mar 30, 2010
    #14
  15. aditya

    Mensanator Guest

    gmpy gives you arbitrary precision floats, also.
     
    Mensanator, Mar 30, 2010
    #15
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.