with: Erik Oosterwal
Decimal Fractions to Binary Fractions
A visitor to this site send me an email asking if it were possible to use
the Numeric Base Conversion algorithm to convert
fractions between bases. I thought it would be pretty straight forward
to implement the change to the general algorithm, but found it was easier
just to make a single purpose algorithm to convert from decimal to binary,
since that was specifically what he asked for. As time allows, I'll
update the algorithm to make it general purpose to convert fractions between
any two bases.
This algorithm borrows from the general Numeric
Base Conversion algorithm, but it has been simplified to only convert
from base 10 to base 2, and an additional portion that converts the fractional
part of the input number to a binary fraction has been added.
Binary fractions are a bit tricky to work with. Some values convert
easily, such as 0.5, 0.375, and 0.75, which are 0.1, 0.011, and 0.11,
respectively, in binary form. Other fractional values, which are easily
displayed in base 10, become long strings of seemingly random bits. For
instance, 1/10 = 0.1 (base 10) = 0.000110011001100110... (base 2), and 1/3
= 0.33333... (base 10) = 0.010011001100110011... (base 2), and 1/100 = 0.01
(base 10) = 0.000000101000111101... (base 2).
If you are already familiar with binary notation, you recognize that each
binary digit represents a power of 2. Starting at the least significant
bit and moving towards the most significant bit, the bits represent 1, 2,
4, 8, 16, 32, 64, 128, etc. Just as decimal fraction digits represent
the inverses of the powers of 10: 1/10, 1/100, 1/1000, etc, binary
fractional bits represent the inverses of the powers of 2: 1/2, 1/4,
1/8, 1/16, etc., which are 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625,
0.0078125, etc. As you can see, we have to take a binary fraction out
to 7 places before we get less than 0.01 (base 10).
The Visual Basic code below will only output 20 bits, including the decimal
point. You can modify this yourself by changing the value assigned
to intNumBits near the top of the listing. The embedded comments in
the code should be fairly explanatory, but if you have questions or comments,
feel free to send me an email at the address listed on the
Home Page of
this site.
Private Sub Dec2Bin_Click()
' Subroutine to convert floating point decimal values to floating point binary values.
'
' Written by: Erik Oosterwal
' Started on: October 26, 2005
' Completed: October 27, 2005
Dim txtNumericBaseData, txtOutputValue As String
Dim intX, intNumBits As Integer
Dim dblDecimalValue, dblFractionValue, dblBinaryFraction As Double
intNumBits = 20 ' The number of bits in the output (including the decimal point)
txtNumericBaseData = "01" ' Output digits can be either "0" or "1"
dblBinaryFraction = 0.5 ' Binary fraction bits are powers of 0.5
txtOutput.Text = "" ' Clear the display
txtOutputValue = "" ' Clear the working output variable
dblDecimalValue = Int(CDbl(txtInput.Text)) ' Get the integer portion of the input
dblFractionValue = CDbl(txtInput.Text) - dblDecimalValue ' Get the fractional portion of the input
' Figure out the integer portion of the input.
While dblDecimalValue > 0
intX = Int(((dblDecimalValue / 2) - Int(dblDecimalValue / 2)) * 2 + 1.5)
txtOutputValue = Mid(txtNumericBaseData, intX, 1) + txtOutputValue
dblDecimalValue = Int(dblDecimalValue / 2)
Wend
If txtOutputValue = "" Then txtOutputValue = "0" ' If there was no whole number, set it to "0"
txtOutputValue = txtOutputValue + "." ' then add a decimal point
' Figure out the fractional portion of the input.
While Len(txtOutputValue) < intNumBits And dblFractionValue > 0 ' As long as we're not exceeding the
' allowed number of bits in the output
' and there's still part of the input
' value to be converted...
If dblFractionValue >= dblBinaryFraction Then ' If the input number is larger than the fraction bit,
txtOutputValue = txtOutputValue + "1" ' add a "1" to the output and
dblFractionValue = dblFractionValue - dblBinaryFraction ' reduce the input number by the fraction bit's value.
Else ' Otherwise...
txtOutputValue = txtOutputValue + "0" ' just tag on a "0" to the end of the output.
End If
dblBinaryFraction = dblBinaryFraction / 2# ' The fraction bit must be cut in half.
Wend
txtOutput.Text = txtOutputValue ' Send the output value to the display.
End Sub
Discuss this algorithm at the Computer Algorithms blog page.
For a more generalized routine that can convert integer values between any
two numeric bases, see the Numeric Base
Conversion article from the main Computer
Science 101 page.
You can also download a zip file that contains
the listing given above as well as an executable file that demonstrates this
routine.
Discuss computer algorithms and other computer science topics at the Computer Algorithms blog page.
All code and original algorithms are © Erik Oosterwal - 1987-2008
Computer Science 101
Dressing for Success