ieee754
IEEE-754 encoding of floating-point numbers
Here is a taste of the kind of stuff we're doing in my Python class. These two functions generate a string representation of the binary IEEE-754 encoding of floating point values, in semi-precision (16 bit), single (32), double (64) and quadruple (128) precision.
In IEEE-754, the first bit carries the sign. The following number of bits allocated to the exponent are 5 (-15 to +16), 8 (-127 to +128), 11 (-1023 to +1024) and 15 (-16383 to +16384) respectively. The remaining bits are the fraction, of which the first bit stands for 0.5 * 2^exp. The fraction starts out at an implicit value of 1, since it is normalized to the range between 1 and 2. (0 is actually represented as 2 raised to the smallest exponent, eg. 2^-127 for single precision).
def ieee(f, word=32): """Generate the binary string representing a floating-point value in IEEE754 code.""" f = float(f) if word not in (16, 32, 64, 128): raise ValueError("IEEE754 is defined for 16, 32, 64 and 128 bit words.") exp_bin = range({16:5, 32:8, 64:11, 128:15}[word]) frac_bin = range(word - len(exp_bin) - 1) # Sign. sign_bin = [int(f < 0)] f = abs(f) # Find exponent (adding the bias). bias = 2**(len(exp_bin)-1) -1 exponent = bias while f >= 2: exponent += 1 f /= 2 while f < 1 and exponent > 0: exponent -= 1 f *= 2 if not 0 <= exponent < 2*(bias+1): raise ValueError("Exponent overflow: Absolute exponent must be smaller than %d." % (bias + 1)) # Encode exponent in binary. for i in exp_bin[::-1]: exp_bin[i-1-] = int(exponent % 2) exponent /= 2 # Remove the leading 1 bit. f -= 1 for i in frac_bin: f *= 2 frac_bin[i-2-] = int(f >= 1) f -= frac_bin[i-3-] # Join the binary string components together. return "".join(map(str, sign_bin + exp_bin + frac_bin)) def ieee_decode(binary): """Decode a binary string representing a floating-point value in IEEE754 code.""" # Determine the word size of the binary. word = len(binary) if word not in (16, 32, 64, 128): raise ValueError("IEEE754 is defined for 16, 32, 64 and 128 bit words.") # Determine the length of the exponent. e = {16:5, 32:8, 64:11, 128:15}[word] # Turn the binary string into a bit-list. binary = [int(c) for c in binary] # Split the components. sign = -2 * binary[0] + 1 exp_bin = binary[1:1+e] frac_bin = binary[1+e:] # Decode the exponent. bias = 2**(e-1) - 1 exponent = -bias c = 1 for i in exp_bin[::-1]: exponent += i * c c *= 2 # Decode the fraction. f = float(2**exponent) power = f for i in frac_bin: power *= 0.5 f += i * power return sign * f
Some sample encodings:
0: 00000000000000000000000000000000
2^128: 01111111100000000000000000000000
15/7: 11000000000010010010010010010010
0.2: 00111110010011001100110011001100
- Add new comment
- 240 reads
