@@ -222,9 +222,9 @@ that a naive implementation cannot handle correctly:
222222 (a ` double ` has only 53 bits of mantissa).
223223
224224Both challenges are addressed by using ** fixed-point arithmetic** : the conversion factor is
225- represented at compile time as a double-width integer constant, so the runtime computation
226- is a pure integer multiply followed by a right-shift with no risk of intermediate overflow
227- and no floating-point operations.
225+ represented at compile time as a widened integer constant (64-bit for types up to 32 bits,
226+ 128-bit for ` int64_t ` ), so the runtime computation is a pure integer multiply followed by
227+ a right-shift with no risk of intermediate overflow and no floating-point operations.
228228
229229??? info "Implementation details"
230230
@@ -238,23 +238,24 @@ and no floating-point operations.
238238 | Non-integer ratio | otherwise | `ft → m` ($\times 0.3048$) | fixed-point multiply | explicit |
239239
240240 For the non-integer case the magnitude is converted **at compile time** to a
241- fixed-point constant with double the bit-width of the representation type. For
242- example, when scaling a 32-bit integer value, a 64 -bit fixed-point intermediate is
243- used . The actual runtime computation is then a pure integer multiply followed by a
244- right-shift:
241+ fixed-point constant with widened bit-width. The library uses **`int64_t` for
242+ all types up to 32 bits** (`int8_t`, `int16_t`, `int32_t`) and **128 -bit arithmetic
243+ for `int64_t`** . The actual runtime computation is then a pure integer multiply
244+ followed by a right-shift:
245245
246246 $$
247247 \text{result} = \left\lfloor \text{value} \times \lfloor M \cdot 2^N \rfloor \right\rfloor \gg N
248248 $$
249249
250- where $N$ equals the bit-width of the source representation type . On platforms where
251- `__int128` is available (most 64-bit targets), the double-width arithmetic is
250+ where $N$ equals 64 for types up to 32 bits, and 128 for `int64_t` . On platforms
251+ where `__int128` is available (most 64-bit targets), the 128-bit arithmetic is
252252 implemented natively; on others, a portable `double_width_int` emulation is used in
253253 `constexpr` context.
254254
255- Because the intermediate is double-width, it cannot overflow as long as the input
256- value fits in the representation type — a value of `std::int64_t` will never silently
257- overflow during the multiplication step.
255+ Because the intermediate is significantly widened (e.g., `int64_t` for types up to
256+ 32 bits, providing much more than double-width headroom for smaller types), it cannot
257+ overflow as long as the input value fits in the representation type — for example,
258+ a value of `std::int32_t` computed in `int64_t` has 32 extra bits of safety margin.
258259
259260 For the non-integer ratio path, the result is **truncated toward zero**. The
260261 fixed-point constant is rounded *away* from zero at compile time to compensate for
0 commit comments