Skip to content

Instantly share code, notes, and snippets.

@Redchards
Created August 23, 2015 21:47
Show Gist options
  • Save Redchards/7f3492d5c2bcbd3f1a25 to your computer and use it in GitHub Desktop.
Save Redchards/7f3492d5c2bcbd3f1a25 to your computer and use it in GitHub Desktop.
A bunch of helper functions to quickly extract information about floating point value. Used mainly for learning. Not production ready by any mean !
import struct
# I do not support Decimal type in this toy code
# This piece of code should just work on python2 and python3
# In general, it will work for single precision, IEEE754 compliant floating point numbers
# Dirty function to avoid having to type the condition in each function
def throwOnNonFloat(num):
if not(type(num) is float):
raise ValueError(str(num) + " is not a floating point number !")
# Converting float to in bitwise
def floatToRaw(num):
throwOnNonFloat(num)
return struct.unpack("=i", struct.pack("=f", num))[0]
# Get precision using b^e-(p-1).
# If you want to learn more, you can check the formal definition on wikipedia
# https://en.wikipedia.org/wiki/Machine_epsilon#Formal_definition (the part on the spacing)
# To explaine a bit more, you can think of it this way :
# We know that the mantissa is normalized in the IEEE754 standard. So, if the mantissa is p bits wide,
# the minimal value of the mantissa is when it is filled with 0s, but the last bit. There is no "1" in front of
# the mantissa, because of the hidden bit. The, the minimal value the mantissa alone can represent is b^-(p-1)
# So, the minimal value mantissa*(b^e) can represent is (b^-(p-1))*b^e = b^(e-(p-1)), hence the function here.
# We have b = 2, p = 24 (defined by IEEE754 standard).
def floatPrecision(num):
throwOnNonFloat(num)
tmp = getExponent(num)
return 2**(tmp-24+1)
# This function extracts each bits and build a string representing the binary representation of a float number.
def floatToBin(num):
throwOnNonFloat(num)
return bin(floatToRaw(num))[2:]
# Same as above, but without using the bin function, extracting bit by bit. No interest in itself, other to show
# another method.
def floatToBin2(num):
throwOnNonFloat(num)
numStr = ""
tmp = floatToRaw(num)
#tmp = cast(pointer(c_float(num)), POINTER(c_int32)).contents.value
for i in range(31, -1, -1):
numStr += str((tmp & (1 << i)) >> i)
return numStr
# All the methods presented here are used to extract some datas from the floating point number.
# The first three functions are considered "Dumb". Indeed, the extraction method is using the string
# provided by the function "floatToBin". Despite being very intuitive, everybody is familiar with string
# manipulations, its a very dumb way to extract datas. A more clever, but counter intuitive way for those
# who don't know there way through bitwise operations, is the three other functions. They present the
# canonic way to do data extraction on int.
# Get the exponent with bias.
def getBiasedExponentDumb(num):
throwOnNonFloat(num)
tmpStr = floatToBin(num)
tmp = 0
for i in range(1, 9):
tmp |= (int(tmpStr[9-i]) << (i-1))
return tmp
# Apply bias to get the real exponent
def getExponentDumb(num):
return getBiasedExponentDumb(num)-127
# Retrieve the mantissa
def getMantissaDumb(num):
throwOnNonFloat(num)
tmpStr = floatToBin(num)
tmp = 0
for i in range(1, 24):
tmp |= (int(tmpStr[32-i]) << (i-1))
return tmp
# Here are more standards functions. We first convert float to int representation, using the fact that both are
# 32 bits in python, and using the safe struct packing. We then extract datas as if it were simple integers !
# The functions give strictly the same results as the functions above.
def getExponentBiased(num):
throwOnNonFloat(num)
return (floatToRaw(num) >> 23) & ((0xff))
def getExponent(num):
return getBiasedExponent(num)-127
def getMantissa(num):
throwOnNonFloat(num)
return (floatToRaw(num) & ((1<<24)-1))
# Retrieve the sign bit using the standard method.
def getSign(num):
return ((floatToRaw(num) & (1<<31)) >> 31)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment