The conversion of a fractional decimal to binary is the mathematical process of translating the non-integer portion of a base-10 number into a base-2 sequence by repeatedly multiplying the fraction by 2 and recording the integer carry bits. In real-world circuits and embedded installations, this conversion is not just academic; it dictates the exact voltage steps in Digital-to-Analog Converters (DACs), determines the quantization error floor in Analog-to-Digital Converters (ADCs), and defines the precise duty cycle registers on microcontrollers like the ESP32 or STM32. When you command a motor driver to run at exactly 33.3% speed or configure a 12-bit ADC to read a 3.3V reference, you are relying on the hardware's ability to map fractional decimals into finite binary registers.
The Core Algorithm and Reference Tables
While the integer portion of a decimal number is converted to binary using the "divide by 2" method, the fractional portion requires the "multiply by 2" algorithm. You take the decimal fraction, multiply it by 2, and record the integer part of the result (which will always be 0 or 1) as the next binary bit. You then take the remaining fractional part and repeat the process until the fraction reaches zero or you hit your hardware's bit-depth limit.
Below is the step-by-step conversion table for the decimal fraction 0.6875, demonstrating how the algorithm terminates cleanly.
| Step | Fraction × 2 | Integer Carry (Bit) | Remaining Fraction | Binary Sequence |
|---|---|---|---|---|
| 1 | 0.6875 × 2 = 1.375 | 1 | 0.375 | 0.1 |
| 2 | 0.375 × 2 = 0.75 | 0 | 0.75 | 0.10 |
| 3 | 0.75 × 2 = 1.5 | 1 | 0.5 | 0.101 |
| 4 | 0.5 × 2 = 1.0 | 1 | 0.0 | 0.1011 |
Because hardware registers rely on fixed binary weights, it is highly useful to memorize or reference the standard fractional binary equivalents. The table below maps common base-10 fractions to their base-2 representations and their corresponding voltage output on a standard 5.0V reference DAC.
| Decimal Fraction | Binary Weight | Binary Representation | Voltage (5.0V Ref) | Common Application |
|---|---|---|---|---|
| 0.5 | 2-1 | 0.1 | 2.500V | Mid-scale bias, comparator thresholds |
| 0.25 | 2-2 | 0.01 | 1.250V | Quadrature encoding, 2-bit flash ADCs |
| 0.125 | 2-3 | 0.001 | 0.625V | Audio DAC baseline steps |
| 0.0625 | 2-4 | 0.0001 | 0.3125V | 4-bit R-2R ladder networks |
| 0.03125 | 2-5 | 0.00001 | 0.15625V | 5-bit PWM dimming steps |
Worked Numeric Example: The 0.1 Decimal Trap
In embedded C and C++, developers frequently attempt to use 0.1 as a clean incremental step for timing loops or motor ramp-ups. However, the conversion of fractional decimal 0.1 to binary reveals a critical hardware limitation: it does not terminate.
Let us run the multiply-by-2 algorithm on 0.1:
- 0.1 × 2 = 0.2 (Bit: 0)
- 0.2 × 2 = 0.4 (Bit: 0)
- 0.4 × 2 = 0.8 (Bit: 0)
- 0.8 × 2 = 1.6 (Bit: 1, remainder 0.6)
- 0.6 × 2 = 1.2 (Bit: 1, remainder 0.2)
- 0.2 × 2 = 0.4 (Bit: 0) ← The sequence 0011 now repeats infinitely.
The binary representation of 0.1 is 0.0001100110011... repeating forever. According to the IEEE 754 standard for floating-point arithmetic, a standard 32-bit float on an Arduino or ESP32 must truncate this sequence at 23 bits. This truncation means the stored value is actually 0.100000001490116119384765625. If you accumulate this value in a while loop to trigger a relay at exactly 1.0 seconds, the relay will fire late due to compounded quantization drift. In safety-critical or precision-timing loops, always use integer math (e.g., counting milliseconds) rather than fractional float accumulation.
Where You Meet This in Practice
The most common jobsite and bench scenarios where you must manually calculate fractional decimal to binary conversions involve configuring Pulse Width Modulation (PWM) and interpreting ADC datasheets.
ESP32 PWM Duty Cycle Configuration
When configuring the LEDC peripheral on an ESP32-WROOM-32, you define a timer resolution. If you select a 10-bit resolution, the hardware register accepts values from 0 to 1023. Suppose your project requires a cooling fan to run at exactly 68.75% capacity. You convert 0.6875 to binary (0.1011), but the hardware doesn't take the raw fraction; it takes the integer mapped to the resolution depth.
You write
704 to the register, which in binary is 1011000000.
// ESP32 Arduino Core PWM Configuration
const int pwmChannel = 0;
const int pwmFreq = 25000; // 25kHz for PC fan
const int pwmResolution = 10; // 10-bit resolution (0-1023)
void setup() {
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(25, pwmChannel); // GPIO 25
// 68.75% duty cycle derived from fractional conversion
int dutyCycle = (int)(0.6875 * pow(2, pwmResolution));
ledcWrite(pwmChannel, dutyCycle);
}
ADC Quantization and LSB Voltage
When reading sensors, the Espressif ESP-IDF documentation and various silicon datasheets define resolution in bits. A 12-bit ADC reading a 3.3V nominal rail has 4096 discrete steps. The Least Significant Bit (LSB) represents the smallest fractional voltage change the ADC can detect. By converting the fraction 1/4096 to decimal (0.00024414), we find the LSB voltage is 3.3V × 0.00024414 = 0.805 mV. If your sensor outputs a 2 mV change per degree Celsius, your binary readout will jump by roughly 2 to 3 integer steps per degree, defining your absolute temperature resolution.
Common Confusions and Mistakes to Avoid
When working with base conversions at the bench, hobbyists and junior engineers frequently fall into two specific traps:
- Confusing the Integer and Fractional Algorithms: The most common mistake is attempting to use the "divide by 2 and record the remainder" method on the fractional part of a number. Division is strictly for the left side of the decimal point (the integer). The right side of the decimal point (the fraction) strictly requires multiplication by 2 and recording the carry. Mixing these up will yield completely invalid binary strings that will brick your register configurations.
- Assuming All Decimals Terminate: As demonstrated with 0.1, many clean-looking base-10 decimals result in infinitely repeating binary fractions. Only fractions that can be expressed as a sum of inverse powers of 2 (e.g., 0.5, 0.25, 0.75, 0.125) terminate cleanly. If your target decimal is something like 0.3 or 0.6, you must explicitly decide how many bits of precision your hardware supports and truncate the math accordingly, accepting the resulting quantization error.
Frequently Asked Questions
Why does my 8-bit DAC output 1.28V instead of 1.30V when I send 0.4?
An 8-bit DAC has 256 steps. 0.4 × 256 = 102.4. Because the hardware register can only accept whole integers, it truncates the value to 102. On a 3.3V reference, 102/255 × 3.3V = 1.317V. If your reference is 5.0V, 102/255 × 5.0V = 2.0V. The discrepancy comes from the hardware's inability to store the fractional 0.4 remainder in an 8-bit binary space. To get closer to 1.30V, you must upgrade to a 10-bit or 12-bit DAC.
Can I convert a mixed number like 5.625 to binary in one step?
No, you must split the number at the decimal point. Convert the integer (5) to binary using division (101), then convert the fraction (0.625) using multiplication (0.101). Recombine them to get 101.101. Attempting to process the mixed number as a single mathematical entity will break the positional weighting of the binary bits.






