When embedded engineers and hobbyists search for a multiplication of binary numbers calculator, they are rarely looking for a simple web widget to multiply 1010 by 0111. In microcontroller programming, FPGA design, and digital signal processing (DSP), binary multiplication is a hardware-constrained operation. The real challenge isn't the arithmetic; it is tracking bit-width growth, managing radix (decimal) point shifts, and preventing silent register overflow in C/C++.

This guide derives the core hardware formulas for binary multiplication, provides data-dense lookup tables for fixed-point math, and walks through worked examples with strict 'unit' tracking—where our units are integer bits, fractional bits, and sign states.

The Core Binary Multiplication Formulas & Symbol Definitions

Binary multiplication in a digital system is governed by two distinct formulas: the mathematical value equation and the hardware bit-width equation. The value equation dictates the numerical result, while the hardware equation dictates the minimum register size required to store that result without truncation.

1. Mathematical Value Formula (Positional Notation):
\( P = \sum_{i=0}^{W_A-1} \sum_{j=0}^{W_B-1} (a_i \cdot b_j) 2^{(i+j) - (R_A + R_B)} \)

2. Hardware Bit-Width Formula (Overflow Prevention):
\( W_P = W_A + W_B \)

3. Radix Point Formula (Fractional Tracking):
\( R_P = R_A + R_B \)

Symbol Definition Hardware Context
\( P \) Product (Result) Stored in a destination register (e.g., 32-bit accumulator)
\( A, B \) Multiplicand and Multiplier Source operands (e.g., ADC reading, filter coefficient)
\( W_A, W_B \) Word length (Total bits) of A and B Includes sign bit for signed types (e.g., 16 for int16_t)
\( W_P \) Word length of the Product Minimum bits required to guarantee zero overflow
\( R_A, R_B \) Radix point position (Fractional bits) Number of bits representing the fractional part (Q-format)
\( R_P \) Radix point position of the Product Determines the required bit-shift to normalize the result
\( a_i, b_j \) Individual bit values (0 or 1) at index \(i, j\) Hardware AND gates in an array multiplier

Data-Dense Reference: Q-Format Multiplication & Overflow Margins

In DSP and motor control, we use Q-format (fixed-point) notation to represent fractions. A Q15 number uses 1 sign bit and 15 fractional bits. When multiplying Q-formats, the radix points add together, requiring a bit-shift to return to the original scale. The table below maps common embedded multiplication scenarios, tracking the exact bit growth and required shifts.

Operand A (Format) Operand B (Format) Raw Product Bits (\(W_P\)) Raw Radix (\(R_P\)) Required Shift Final Normalized Format
Q15 (Signed 16-bit) Q15 (Signed 16-bit) 32 bits 30 Right 15 Q15 (fits in 32-bit, truncate to 16)
12-bit ADC (Unsigned Q0) Gain Factor (Signed Q15) 28 bits 15 Right 15 Signed 13-bit integer (Q0)
Q8 (Signed 16-bit) Q8 (Signed 16-bit) 32 bits 16 Right 8 Q8 (fits in 16-bit after shift)
8-bit Audio (Signed Q0) 8-bit Volume (Unsigned Q0) 16 bits 0 None 16-bit Unsigned Integer (Q0)
Q31 (Signed 32-bit) Q31 (Signed 32-bit) 64 bits 62 Right 31 Q31 (requires 64-bit accumulator)

Worked Examples: Tracking Bits, Radix Points, and Sign States

In binary math, 'unit tracking' means tracking Integer bits (I), Fractional bits (F), and Sign bits (S). Failing to track these is the primary cause of erratic behavior in DIY DSP projects and Arduino sensor scaling.

Problem 1: Scaling a 12-bit ADC Reading with a Fractional Gain

Scenario: You are reading an ESP32 12-bit ADC (0 to 4095) and want to multiply it by a calibration gain of 0.75. You represent 0.75 in Q15 format (0.75 × 32768 = 24576).

  1. Define Operand Units:
    ADC (A): 12 bits total. 0 Sign, 12 Integer, 0 Fractional. Format: UQ12.0.
    Gain (B): 16 bits total. 1 Sign, 0 Integer, 15 Fractional. Format: Q0.15 (value 24576).
  2. Calculate Raw Product Width:
    \( W_P = 12 + 16 = 28 \) bits. (Must use a 32-bit int32_t register to hold the intermediate result).
  3. Calculate Raw Radix Point:
    \( R_P = 0 + 15 = 15 \) fractional bits.
  4. Execute Multiplication:
    Assume ADC reads 2000. \( 2000 \times 24576 = 49,152,000 \).
  5. Apply Normalization Shift:
    Shift right by \( R_P \) (15 bits): \( 49,152,000 \gg 15 = 1500 \).
  6. Verify Magnitude:
    \( 2000 \times 0.75 = 1500 \). The units resolve perfectly to an Integer (Q0) result.

Problem 2: Signed 8-bit Audio Sample Multiplied by Signed 8-bit Volume

Scenario: Multiplying an 8-bit signed PCM audio sample (-128 to 127) by an 8-bit signed volume control (-128 to 127) to invert and amplify the phase.

  1. Define Operand Units:
    Audio (A): 8 bits. 1 Sign, 7 Integer. Format: Q7.0.
    Volume (B): 8 bits. 1 Sign, 7 Integer. Format: Q7.0.
  2. Calculate Raw Product Width:
    \( W_P = 8 + 8 = 16 \) bits. (Fits perfectly in a standard 16-bit int16_t without truncation).
  3. Calculate Raw Radix Point:
    \( R_P = 0 + 0 = 0 \) fractional bits.
  4. Execute Multiplication (Worst Case):
    \( -128 \times -128 = 16,384 \).
  5. Analyze the Edge Case:
    A 16-bit signed integer maxes out at +32,767. The result 16,384 fits. However, if the hardware multiplier doesn't automatically sign-extend the 8-bit operands to 16-bit before multiplying, the math will corrupt. In C/C++, you must explicitly cast: (int16_t)A * (int16_t)B.

When the Formula Applies (and Which Mistakes Break It)

The formulas \( W_P = W_A + W_B \) and \( R_P = R_A + R_B \) assume standard two's complement arithmetic and fixed-point positional weighting. They apply to hardware multipliers, ALU instructions, and software implementations of DSP filters.

Critical 'Unit' Mistakes That Break Binary Multiplication

  • Mixing Signed and Unsigned Operands: If you multiply a signed 8-bit number by an unsigned 8-bit number in C, the compiler implicitly promotes both to standard signed integers. If the unsigned number has its MSB high (e.g., 0x80), it is treated as a negative number during promotion, destroying the math. Fix: Explicitly cast both to int16_t or uint16_t before multiplying.
  • Ignoring the Radix Shift: If you multiply two Q15 numbers and store the raw 32-bit result without shifting right by 15, your output magnitude will be \( 2^{15} \) (32,768) times larger than reality. This is the #1 reason DIY motor controllers spin out of control on startup.
  • Truncating Before Shifting: If you multiply two 16-bit numbers, store the result in a 16-bit variable, and then try to shift, the upper 16 bits of the product are already lost. Fix: Always store the raw product in a register where \( W \ge W_A + W_B \).

Rearranged Forms for Embedded Register Sizing

When designing custom PCBs or writing bare-metal firmware, you often know your target register size and need to work backward to find the maximum allowable sensor resolution or coefficient format. Here are the rearranged forms of the hardware formulas:

  • Solving for Maximum Multiplicand Width (\( W_A \)):
    \( W_A = W_P - W_B \)
    Use case: Your microcontroller only has a native 16-bit hardware multiplier (\( W_P = 16 \)). Your filter coefficient requires 10 bits (\( W_B = 10 \)). Therefore, your ADC reading cannot exceed 6 bits (\( W_A = 6 \)) without causing hardware overflow.
  • Solving for Required Input Radix (\( R_A \)):
    \( R_A = R_P - R_B \)
    Use case: You need the final product to have 8 fractional bits (\( R_P = 8 \)) for a PWM duty cycle calculation. Your multiplier is a Q12 constant (\( R_B = 12 \)). Therefore, your input sensor data must be formatted with a radix of -4 (meaning it must be shifted left by 4, or it represents integers scaled up by 16) to balance the equation.
  • Solving for Missing Operand Value (\( A \)):
    \( A = P \gg R_P / B \)
    Use case: Debugging a black-box DSP filter where you know the output \( P \), the shift \( R_P \), and the coefficient \( B \), allowing you to reverse-engineer the input sample \( A \).

For deeper implementation details on fixed-point math on modern microcontrollers, refer to the Analog Devices guide on fixed-point arithmetic, or consult the Arduino data type references to understand how implicit promotion affects your specific board's architecture.