To convert the decimal fraction 0.625 to binary, the exact mathematical answer is 0.101. If you are scaling this for a 12-bit microcontroller ADC reading a 3.3V reference, the integer binary equivalent is 001010000000 (hex 0x280, decimal 640). The formula used is repeated multiplication by 2, recording the integer carry: $0.625 \times 2 = 1.25$ (record 1, keep 0.25), $0.25 \times 2 = 0.5$ (record 0, keep 0.5), $0.5 \times 2 = 1.0$ (record 1, keep 0.0). This terminates cleanly, giving 0.101.
The Core Formula and Neighboring Values
In digital signal processing and microcontroller programming, you rarely use raw binary fractions (like 0.101). Instead, you scale the decimal fraction to the maximum integer value of your ADC or data bus. For a 12-bit system, the maximum value is $2^{12}-1 = 4095$. Multiplying your decimal fraction by 4095 gives the integer register value.
| Decimal Fraction | Pure Binary Fraction | 12-Bit ADC Integer (Decimal) | 12-Bit ADC Integer (Hex) |
|---|---|---|---|
| 0.500 | 0.1 | 2048 | 0x800 |
| 0.550 | 0.100011... | 2253 | 0x8CD |
| 0.600 | 0.100110... | 2458 | 0x99A |
| 0.625 | 0.101 | 2560 | 0xA00 |
| 0.650 | 0.101001... | 2662 | 0xA66 |
| 0.700 | 0.101100... | 2867 | 0xB33 |
| 0.750 | 0.11 | 3072 | 0xC00 |
Notice how fractions like 0.550 and 0.600 result in repeating binary sequences. This leads directly to the most critical constraint in embedded math: precision limits.
The Assumption That Fixes the Answer: Bit-Depth and Precision
When is the conversion meaningless? If you attempt to convert a decimal fraction like 0.1 into binary without defining a bit-depth or floating-point standard, the conversion is mathematically meaningless for a microcontroller. It results in an infinite repeating sequence ($0.0001100110011..._2$). You must assume a truncation boundary to make the answer actionable.
The answer is fixed by your bit-depth assumption. In fixed-point math (like the Q-format used in TI DSPs), you assume a specific number of fractional bits. If you assume a Q12 format (12 fractional bits), the decimal 0.1 is multiplied by $2^{12}$ (4096), truncated to the nearest integer (410), and stored as
0x019A. Without this assumption, the hardware cannot allocate memory for the variable.
For rigorous floating-point representation, the assumption shifts to the IEEE 754-2019 standard, which allocates 32 bits (single precision) or 64 bits (double precision) to handle the sign, exponent, and mantissa, allowing the hardware FPU to manage the repeating fractions natively.
Shifting Contexts: 3.3V Logic vs. 120V/230V Mains Scaling
In embedded power monitoring, a 0.0–1.0 decimal fraction often represents the normalized output of an AC voltage sensor (like the ZMPT101B active voltage transformer module). The binary fraction representing a specific point on the waveform shifts drastically depending on your physical scaling.
- 3.3V Logic (ESP32 ADC): A fraction of 0.625 maps directly to 2.0625V. On a 12-bit ADC, this is
0xA00. - 120V RMS Mains (North America): The peak voltage is ~170V. If your sensor scales 170V peak to 3.3V, a 0.625 fraction represents 106.25V instantaneous. The binary register remains
0xA00. - 230V RMS Mains (Europe/UK): The peak voltage is ~325V. If you use the exact same ZMPT101B hardware without changing the voltage divider resistors, 325V peak will saturate and clip the 3.3V ADC. To fix this, you must scale the voltage divider down by a factor of ~1.91. Now, 0.625 of the *new* scaled range represents a different physical voltage, and if you want to measure the exact same 106.25V instantaneous point on a 230V circuit, your ADC fraction shifts to ~0.327, yielding a binary register value of
0x53A(1338).
The pure binary math doesn't change, but the physical mapping of that binary fraction requires hardware and firmware recalibration when crossing between 120V and 230V environments.
Decision Path: Choosing Your Binary Format
Use this decision tree to select the exact C data type and scaling method for your next ESP32 or Arduino firmware build.
| Condition / Use Case | Required Action | Concrete Pick (Data Type) |
|---|---|---|
| Raw ADC readings, no negative values, no complex math | Scale fraction by $2^n-1$ and store directly | uint16_t |
| Audio processing, motor control, or fast PID loops (FPU unavailable or too slow) | Multiply fraction by $2^{15}$, use bitwise shifts for math | int16_t (Q15 format) |
| General sensor averaging, UI displays, slow control loops | Let the hardware FPU handle the repeating fractions | float (IEEE 754 32-bit) |
| High-precision energy metering (e.g., 24-bit Sigma-Delta ADC) | Scale fraction by $2^{24}$, use 64-bit math to prevent overflow | int32_t or int64_t |
Default Recommendation: If you are building a standard IoT sensor node on an ESP32 and need to transmit fractional values over MQTT, use float for the math, but cast to a scaled uint16_t (e.g., value * 100) before serialization to save bandwidth and avoid JSON floating-point parsing errors on the receiving dashboard.
FAQ: Edge Cases in Fractional Binary Math
Why does my 0.1 decimal fraction print as 0.10000000149 in the serial monitor?
This is the classic IEEE 754 floating-point representation error. The decimal 0.1 cannot be represented perfectly in binary. The 32-bit float standard stores the closest possible approximation, which evaluates to ~0.100000001490116. To fix this in your serial output, use formatting functions like Serial.print(val, 1) to force rounding to one decimal place, or switch to fixed-point integer math.
How do I convert a binary fraction back to decimal in C code?
If you have a raw 12-bit ADC integer (e.g., 640) and need the 0.0–1.0 decimal fraction, divide by the maximum value using floating-point casting: float fraction = (float)adc_raw / 4095.0;. Never use integer division (640 / 4095), as C will truncate the result to 0.
Does the binary fraction change if I use a 10-bit vs 12-bit ADC?
The pure mathematical fraction (0.101) remains identical. However, the integer register value shifts. On a 10-bit ADC (max 1023), 0.625 becomes 640 (0x280). On a 12-bit ADC (max 4095), 0.625 becomes 2560 (0xA00). Always check your microcontroller's datasheet to confirm the active resolution before writing your scaling formulas.






