Fractional binary to decimal conversion is the mathematical process of translating the digits to the right of a binary point into a base-10 decimal value by summing the negative powers of two. While whole-number binary conversion is second nature to most embedded developers and electronics hobbyists, fractional binary is frequently glossed over in introductory tutorials. Yet, it is the exact mathematical foundation that determines analog voltage outputs, sensor scaling, and signal resolution on the bench.
Think of a machinist's ruler: the main inch marks are whole numbers, but the subdivisions are halves, quarters, eighths, and sixteenths of an inch. Binary fractions operate on the exact same physical principle, subdividing a whole unit into progressively smaller powers of two rather than powers of ten.
The Core Math and Place Value Table
In the base-10 decimal system, digits to the right of the decimal point represent tenths ($10^{-1}$), hundredths ($10^{-2}$), and thousandths ($10^{-3}$). In base-2, digits to the right of the binary point represent halves ($2^{-1}$), quarters ($2^{-2}$), eighths ($2^{-3}$), and so on. To convert a fractional binary number to decimal, you simply multiply each bit by its corresponding negative power of two and sum the results.
Below is the reference table for the first eight fractional bit positions. Keep this handy when calculating Least Significant Bit (LSB) voltages for digital-to-analog converters (DACs) or analyzing PWM duty cycles.
| Bit Position (Right of Point) | Negative Power of 2 | Decimal Weight | Cumulative Max Value |
|---|---|---|---|
| 1st (MSB of fraction) | $2^{-1}$ | 0.5 | 0.5 |
| 2nd | $2^{-2}$ | 0.25 | 0.75 |
| 3rd | $2^{-3}$ | 0.125 | 0.875 |
| 4th | $2^{-4}$ | 0.0625 | 0.9375 |
| 5th | $2^{-5}$ | 0.03125 | 0.96875 |
| 6th | $2^{-6}$ | 0.015625 | 0.984375 |
| 7th | $2^{-7}$ | 0.0078125 | 0.9921875 |
| 8th (LSB of 8-bit fraction) | $2^{-8}$ | 0.00390625 | 0.99609375 |
Notice that no matter how many bits you add to the right of the binary point, the cumulative value will approach but never quite reach 1.0. This is a critical concept when calculating the maximum output voltage of a DAC; an 8-bit DAC can never output exactly the full reference voltage, it will always be one LSB short.
Step-by-Step Worked Conversion Example
Let's convert the fractional binary number 0.101101 into a base-10 decimal. We ignore the whole number portion (which is 0) and focus strictly on the bits following the binary point.
- 1st bit (1): $1 \times 2^{-1} = 0.5$
- 2nd bit (0): $0 \times 2^{-2} = 0$
- 3rd bit (1): $1 \times 2^{-3} = 0.125$
- 4th bit (1): $1 \times 2^{-4} = 0.0625$
- 5th bit (0): $0 \times 2^{-5} = 0$
- 6th bit (1): $1 \times 2^{-6} = 0.015625$
Now, sum the non-zero weights:
0.5 + 0.125 + 0.0625 + 0.015625 = 0.703125
The binary fraction 0.101101 is exactly 0.703125 in decimal. If this binary string were fed into a 6-bit DAC with a 5.0V reference voltage, the analog output pin would measure exactly $0.703125 \times 5.0V = 3.515625V$ (assuming an ideal, noise-free environment).
Where You Meet This in Practice: DACs, ADCs, and PWM
Understanding this conversion is not just an academic exercise; it directly dictates hardware behavior in real circuits and installations. Specifically, it defines the exact voltage step size (LSB) of a DAC, the precision scaling of an ADC reading, and the true duty cycle resolution of a PWM signal.
Digital-to-Analog Converters (DACs)
Take the classic ESP32 development board (original revision), which features an 8-bit DAC on GPIO 25 and GPIO 26. The DAC accepts integer values from 0 to 255. However, electrically, the DAC is interpreting these integers as fractions of its reference voltage (typically 3.3V). When you write dacWrite(25, 128), you are sending the binary integer 10000000. In fractional terms relative to the 256-step scale, this represents exactly $128/256$, or 0.10000000 in binary fractions. Converting that fraction to decimal yields exactly 0.5. Multiplying by the 3.3V reference gives an output of 1.65V. For a deeper look at how microcontrollers handle these peripherals, refer to the Espressif ESP32 DAC API documentation.
Analog-to-Digital Converters (ADCs)
When reading a sensor with a 12-bit ADC (like the ADS1115 or the internal ADC on an STM32), a raw reading of 0x800 (hexadecimal for 2048) means the input voltage is exactly halfway up the scale. In binary, 2048 out of 4096 is 0.100000000000. Converting that fractional binary to decimal instantly tells you the voltage is 0.5 of your reference. If your reference is 5.0V, the measured voltage is 2.5V. Understanding the fractional math allows you to write highly optimized bit-shift scaling code in C/C++ rather than relying on slow floating-point division.
PWM Duty Cycles
Pulse Width Modulation relies entirely on fractional time. A 10-bit PWM timer counting from 0 to 1023 set to a compare value of 256 yields a duty cycle of $256/1024$. In binary fractions, this is 0.0100000000, which converts cleanly to a decimal duty cycle of 0.25, or 25%. See this All About Circuits guide on ADC/DAC fundamentals for more on how digital resolution maps to analog reality.
A common mistake when debugging DAC circuits is expecting an 8-bit DAC with a 5V reference to output exactly 5.0V when sent the maximum value (255). Because the maximum fractional binary value
0.11111111 converts to 0.99609375, the maximum physical output will be $0.99609375 \times 5V = 4.9804V$. If your circuit requires a true 5.0V rail, you must use an external op-amp gain stage or a higher reference voltage.
Common Confusions and Microcontroller Implementation
When working with binary fractions in embedded C or assembly, makers commonly confuse fractional binary with two's complement. Two's complement is a method for representing negative integers (like -5 or -12), not fractional values. A binary point does not exist in standard two's complement integer math.
Another frequent point of confusion is conflating fixed-point fractional math (often called Q-format in DSP and motor control) with IEEE 754 floating-point representations.
- Fixed-Point (Q-format): The microcontroller treats a standard integer register as if it has an implied binary point. For example, in Q15 format, a 16-bit integer is treated as having 1 bit for the sign and 15 bits for the fraction. The math is extremely fast because it uses native integer ALU instructions, but the decimal weight of each bit is fixed by the programmer's assumption.
- Floating-Point (IEEE 754): The number is split into a sign bit, an exponent, and a mantissa. The binary point 'floats' based on the exponent value. This allows for massive dynamic range (like $1.2 \times 10^{-38}$) but requires dedicated Floating Point Unit (FPU) hardware or slow software emulation on basic 8-bit and 32-bit microcontrollers.
If you are writing firmware for a motor controller or an audio DSP where timing is critical, you will almost always use fixed-point fractional binary math. You manually track where the binary point belongs, perform integer multiplication, and then bit-shift the result back into alignment. This avoids the clock-cycle penalty of floating-point division while maintaining the precise decimal weights outlined in the table above.
Quick Conversion Trick for the Bench
If you need to convert a binary fraction to decimal in your head while probing a board, use the 'double and add' method from left to right, but divide by 2 at each step. Alternatively, convert the fractional bits to a standard integer, then divide by $2^n$ (where $n$ is the number of fractional bits). For example, the fraction 0.110 has 3 bits. The integer 110 in binary is 6. Divide 6 by $2^3$ (which is 8). $6 / 8 = 0.75$. This integer-division shortcut is exactly how microcontroller compilers optimize fractional scaling under the hood.






