Skip to the content.

generalized sizing

This chapter documents the generalized fixed-point sizing behavior supported by Fxp.

The core interpretation is:

value = integer * 2**(-n_frac)

Where:

This means storage width (n_word) and scaling (n_frac) are intentionally decoupled.

rationale

In many practical DSP and hardware workflows, fixed-point values are treated as:

This allows format changes and reinterpretation without moving data, and supports intermediate representations used by quantized pipelines.

sizing relations

Fxp derives integer bits (n_int) as:

So unusual combinations can be valid, including negative n_int.

supported edge cases

1) negative fractional bits (n_frac < 0)

Binary point is to the right of the LSB.

from fxpmath import Fxp

x = Fxp(16, signed=True, n_word=8, n_frac=-2)
print(x.dtype, x.n_int, x())
# fxp-s8/-2 9 16.0

2) fractional bits greater than word bits (n_frac > n_word)

Binary point is to the left of the MSB.

from fxpmath import Fxp

y = Fxp(-3, signed=True, n_word=1, n_frac=10)
print(y.dtype, y.n_int, y.raw(), y())
# fxp-s1/10 -10 -1 -0.0009765625

3) negative integer bits (n_int < 0)

This is the same geometric interpretation as case (2): binary point outside the stored word.

from fxpmath import Fxp

z = Fxp(1, signed=False, n_word=4, n_frac=5)
print(z.dtype, z.n_int, z.raw(), z())
# fxp-u4/5 -1 15 0.46875

4) zero fractional bits (n_frac = 0)

Pure integer scaling in fixed-point form.

from fxpmath import Fxp

w = Fxp(7, signed=True, n_word=8, n_frac=0)
print(w.dtype, w.n_int, w())
# fxp-s8/0 7 7.0

5) zero integer bits (n_int = 0)

Pure fractional-style range, commonly used for normalized signals and coefficients.

from fxpmath import Fxp

u = Fxp(0.75, signed=True, n_word=8, n_frac=7)
print(u.dtype, u.n_int, u())
# fxp-s8/7 0 0.75

signedness and overflow are orthogonal

Sizing only defines representable range and precision. Runtime behavior at limits depends on configuration:

Example:

from fxpmath import Fxp

a = Fxp(20.0, signed=False, n_word=4, n_frac=0, overflow='wrap')
b = Fxp(20.0, signed=False, n_word=4, n_frac=0, overflow='saturate')

print(a())  # wrapped modulo range
print(b())  # clipped to max

practical guidance