Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary/Hex Floating Point Entry

Why are decimal points only allowed in base 10? Why does the following raise a syntax error?

0b1011101.1101

Is there some ambiguity to the number I'm typing? It seems there is no possible number that string could represent other than 93.8125

The same issue applies to other bases as well:

0x5d.d

I can program my way around this with a fairly straightforward function:

def base_float(number_string, base):
    n = number_string.split('.')
    number = int(n[0], base)
    if len(n) > 1 and len(n[1]):
        frac_part = float(int(n[1], base)) / base**len(n[1])
        if number < 0:
            frac_part = -frac_part
        number += frac_part
    return number

And it gives me the representation I expected:

>>> base_float('0b1011101.1101', 2)
93.8125

int accepts arbitrary base, but no decimal point, and float accepts a decimal point but no arbitrary base. Why?

like image 766
mhlester Avatar asked Jan 28 '14 06:01

mhlester


People also ask

How do you represent 0.1 in binary?

The number 0.1 in binary The number 0.1 can be represented in binary as 0.00011001100110011... . The pattern of 0011 repeats infinitely. We can't store the binary equivalent of decimal 0.1 . As we know, 0.1 is equal to 1/10 .

How do you calculate binary floating number?

To convert the fractional part to binary, multiply fractional part with 2 and take the one bit which appears before the decimal point. Follow the same procedure with after the decimal point (.) part until it becomes 1.0.


1 Answers

Well they are called decimal points ;)

You could use a sort of scientific* notation

>>> 0b10111011101 * 0b10**-4
93.8125
>>> 0x5dd * 0x10**-1
93.8125
>>> 938125 * 10**-4 # note power is number of "decimal" places to shift
93.8125

* yes I realise this is not really scientific notation

Edit

Out of curiosity, I used the dis module to disassemble the byte code for a simple these statements to see if they were calculated at run-time or not

>>> import dis
>>> def f():
...     return 0x5dd * 0x10**-1
...
>>> dis.dis(f)
  2           0 LOAD_CONST               6 (93.8125)
              3 RETURN_VALUE

So it looks like you shouldn't see a performance penalty when using this method.

Edit 2

... Unless you use Python 2

>>> import dis
>>> def f():
...     return 0x5dd * 0x10**-1
...
>>> dis.dis(f)
  2           0 LOAD_CONST               1 (1501)
              3 LOAD_CONST               4 (0.0625)
              6 BINARY_MULTIPLY
              7 RETURN_VALUE
like image 192
Peter Gibson Avatar answered Oct 05 '22 12:10

Peter Gibson