Displaying binary representations of Floats
Posted: Sun May 28, 2006 3:44 pm
Code updated for 5.20+
I've been playing around with floating point numbers and trying to understand how they are stored using binary. I think i've got a pretty good handle on it now and come up with this code. It allows you to input a number in the 'DecimalNumber.s' var to examine, then display usefull info in the Debug Output window.
I'm pretty sure this code can handle any number to be stored in a float but i keep reading things about 'Denormal Numbers'! I can't seem to find a source which can explain these to me other than stuff that looks like a rocket science manual. So if any one can fill me in to what they are i would be grateful. 
I've been playing around with floating point numbers and trying to understand how they are stored using binary. I think i've got a pretty good handle on it now and come up with this code. It allows you to input a number in the 'DecimalNumber.s' var to examine, then display usefull info in the Debug Output window.
Code: Select all
;For all 32 bit floating point numbers encoded in the IEEE 754 standard,
;the bits are arranged like this:
;
;Sign bit Exponent Significand (Mantissa)
;0 00000000 00000000000000000000000
;
;31 30----23 22-----bit index------0
;
;1 bit for the sign, 8 bits for the exponent and 23 bits for the significand.
;
;]=============================================================================
;-CONSTANTS
;[=============================================================================
#SIZE_OF_SIGN = 1 ;bit
#SIZE_OF_EXPONENT = 8 ;bits
#SIZE_OF_SIGNIFICAND = 23 ;bits
#EXPONENT_BIAS = 127
;]=============================================================================
;-PROCEDURES
;[=============================================================================
Procedure.q ValB(String.s)
Protected Result.q
Protected Pointer.l = @String
For x.l = 1 To Len(String)
Result = (Result << 1) + PeekC(Pointer) - 48
Pointer + SizeOf(Character)
Next x
ProcedureReturn Result
EndProcedure
;]=============================================================================
;-MAIN
;[=============================================================================
;Type a decimal floating point number here to examine:
DecimalNumber.s = "0.1"
;Examinations:
FloatingPointNumber.f = ValF(DecimalNumber)
BinaryString.s = RSet(Bin(PeekL(@FloatingPointNumber)), 32, "0")
SignBitString.s = Mid(BinaryString, 1, #SIZE_OF_SIGN)
ExponentString.s = Mid(BinaryString, 1 + #SIZE_OF_SIGN, #SIZE_OF_EXPONENT)
SignificandString.s = Mid(BinaryString, 1 + #SIZE_OF_SIGN + #SIZE_OF_EXPONENT, #SIZE_OF_SIGNIFICAND)
Debug "Original Decimal Floating Point Number: "
Debug DecimalNumber
Debug ""
Debug "-----------------------------------------------------------------------"
Debug "Internal Binary Representation:"
Debug StrF(FloatingPointNumber, 18) + " - (" + BinaryString + ")"
Debug ""
Debug "Sign bit: " + SignBitString
Debug "Exponent: " + ExponentString + " (" + Str(ValB(ExponentString) - #EXPONENT_BIAS) + ")"
Debug "Significand: " + "(1.)" + SignificandString
Debug "-----------------------------------------------------------------------"
Debug ""
;Read the floating point number from its binary source:
Exponent.q = ValB(ExponentString) - #EXPONENT_BIAS
If Exponent < 0
SignificandString = RSet("1" + SignificandString, #SIZE_OF_SIGNIFICAND + -Exponent, "0")
IntegerPart.q = 0
FractionalPart.q = ValB(SignificandString)
Else
IntegerPart.q = ValB("1" + Mid(SignificandString, 1, Exponent))
FractionalPart.q = ValB(Mid(SignificandString, Exponent + 1, #SIZE_OF_SIGNIFICAND - Exponent))
EndIf
;Display the floating point number read from binary:
Debug "The floating point number re-read from binary is:"
If SignBitString = "1"
Debug "-" + StrF(IntegerPart + FractionalPart / Pow(2, #SIZE_OF_SIGNIFICAND - Exponent), 18)
Else
Debug StrF(IntegerPart + FractionalPart / Pow(2, #SIZE_OF_SIGNIFICAND - Exponent), 18)
EndIf
Debug ""
Debug ""
