SkillAgentSearch skills...

Fxpmath

A python library for fractional fixed-point (base 2) arithmetic and binary manipulation with Numpy compatibility.

Install / Use

/learn @francof2a/Fxpmath

README

<img src="./docs/figs/fxpmath_logotipo.png" width="300">

A python library for fractional fixed-point (base 2) arithmetic and binary manipulation with Numpy compatibility.

Some key features:

  • Fixed-point signed and unsigned numbers representation.
  • Arbitrary word and fractional sizes. Auto sizing capability. Extended precision capability.
  • Arithmetic and logical (bitwise) operations supported.
  • Input values can be: int, float, complex, list, numpy arrays, strings (bin, hex, dec), Decimal type.
  • Input rounding methods, overflow and underflow behaviors and flags.
  • Binary, Hexadecimal, and other bases representations (like strings).
  • Indexing supported.
  • Linear scaling: scale and bias.
  • Numpy backend.
  • Suppport for Numpy functions. They can take and return Fxp objects.
  • Internal behavior configurable: inputs/outputs formating, calculation methods.

visit documentation for more information.

See some examples in the examples folder.


GitHub

GitHub tag (latest SemVer)

PyPI PyPI - Python Version

Conda Conda


Table of content


install

To install from pip just do the next:

pip install fxpmath

To install with conda just do the next:

conda install -c francof2a fxpmath

Or you can clone the repository doing in your console:

git clone https://github.com/francof2a/fxpmath.git

and then go to the fxpmath folder and install it:

cd fxpmath
pip install .

citation

Alcaraz, F., 2020. Fxpmath. Available at: https://github.com/francof2a/fxpmath.

BibTex format:

@online{alcaraz2020fxpmath,
  title={fxpmath},
  author={Alcaraz, Franco},
  year={2020},
  publisher={GitHub},
  url={https://github.com/francof2a/fxpmath},
}

quick start

creation

Let's jump into create our new fractional fixed-point variable:

from fxpmath import Fxp

x = Fxp(-7.25)      # create fxp variable with value 7.25
x.info()

dtype = fxp-s6/2
Value = -7.25

We have created a variable of 6 bits, where 1 bit has been reserved for sign, 2 bits for fractional part, and 3 remains for integer part. Here, bit sizes had been calculated to just satisfy the value you want to save.

But the most common way to create a fxp variable beside the its value is defining explicitly if it is signed, the number of bits for whole word and for the fractional part.

Note: dtype of Fxp object is a propietary type of each element stored in it. The format is:

fxp-<sign><n_word>/<n_frac>-{complex}

i.e.: fxp-s16/15, fxp-u8/1, fxp-s32/24-complex

x = Fxp(-7.25, signed=True, n_word=16, n_frac=8)

or just

x = Fxp(-7.25, True, 16, 8)

Formats can also be specified using a string, either in the fxp dtype format, or by using Qm.n or UQm.n notation (or the equivalent Sm.n/Um.n notation).

x = Fxp(-7.25, dtype='fxp-s16/8')
x = Fxp(-7.25, dtype='S8.8')

You can print more information only changing the verbosity of info method.

x.info(verbose=3)

dtype = fxp-s16/8
Value = -7.25

Signed = True
Word bits = 16
Fract bits = 8
Int bits = 7
Val data type = <class 'float'>

Upper = 127.99609375
Lower = -128.0
Precision = 0.00390625
Overflow = saturate
Rounding = trunc
Shifting = expand

Representations

We can representate the value stored en x in several ways:

x

fxp-s16/8(-7.25)

x.get_val()     # return a Numpy array with the val/values in original data type representation
x()             # equivalent to x.get_val() or x.astype(self.vdtype)

-7.25

In different bases:

x.bin()
x.bin(frac_dot=True)    # binary with fractional dot
x.base_repr(2)          # binary with sign symbol (not complement)
x.hex()
x.base_repr(16)         # hex with sign symbol (not complement)

'1111100011000000'
'11111000.11000000'
'-11101000000'
'0xF8C0'
'-740'

In different types:

x.astype(int)
x.astype(float)
x.astype(complex)

-8
-7.25
(-7.25+0j)

Note that if we do:

x.val

we will get the fixed point value stored in memory, like an integer value. Don't use this value for calculations, but in some cases you may need it.

changing values

We can change the value of the variable in several ways:

x(10.75)            # the simpliest way
x.set_val(2.125)    # another option

DO NOT DO THIS:

x = 10.75           # wrong

because you are just modifying x type... it isn't a Fxp anymore, just a simple float right now.

The same as x.val gives you the raw underlying value, you can set that value with

x.set_val(43, raw=True)

changing size

If we want to resize our fxp variable we can do:

x.resize(True, 8, 6)    # signed=True, n_word=8, n_frac=6

For NumPy reshape dispatch, use:

np.reshape(x, (1, 4))

With NumPy >= 2.4, this is also supported:

np.reshape(x, shape=(1, 4))

If you call fxpmath.functions.reshape directly, both keyword styles are accepted:

from fxpmath import functions

functions.reshape(x, shape=(1, 4))
functions.reshape(x, newshape=(1, 4))

data types supported

Fxp can handle following input data types:

  • int, uint
  • float
  • complex
  • list
  • ndarrays (n-dimensional numpy arrays)
  • strings (bin, hex, dec)
  • Fxp objects

Here some examples:

x(2)
x(-1.75)
x(-2.5 + 1j*0.25)
x([1.0, 1.5, 2.0])
x(np.random.uniform(size=(2,4)))
x('3.5')
x('0b11001010')
x('0xA4')

indexing

If we had been save a list or array, we can use indexing just like:

x[2] = 1.0      # modify the value in the index 2
print(x[2])

arithmetic

Fxp supports some basic math operations like:

0.75 + x    # add a constant
x - 0.125   # substract a constant
3 * x       # multiply by a constant
x / 1.5     # division by a constant
x // 1.5    # floor division by a constant
x % 2       # modulo
x ** 3      # power

This math operations using a Fxp and a constant returns a new Fxp object with a precision that depends of configuration of Fxp object, x.config for examples above.

The constant is converted into a new Fxp object before math operation, where the Fxp size for the constant operand is defined by x.config.op_input_size in examples above. The default value for op_input_size is 'best' (best enoguh precision to represent the constant value), but it could be used 'same' to force the constant's size equals to Fxp object size (x in the examples).

Important note:

A power operation with a constant could be time consuming if base number has many fractional bits. It's recommended to do x ** Fxp(3) in the previous example.

The result of math operation is returned as a new Fxp object with a precision defined according to x.config.const_op_sizing. This parameter could be configured with following options: 'optimal', 'same' (default), 'fit', 'largest', 'smallest'. For math operations with constants, by default (config.const_op_sizing = 'same'), a Fxp with same size is returned.

In all these cases we can assign the result to a (Fxp) variable, or to the same (overwritting the old Fxp object).

y = 3.25 * (x - 0.5)    # y is a new Fxp object

Math operations using two or more Fxp variables is also supported, returning a new Fxp object like before cases. The size of returned Fxp object depends of both Fxp operand's sizes and the config.op_sizing parameter of the first (left) Fxp object. By default, config.op_sizing = 'optimal', so, the returned size depends also of the math operation type. For example, in the addition case, the integer size of returned Fxp is 1 bit larger than largest integer size of operands, and size of fractional part of returned Fxp is equal to largest fractional size of operands.

# Fxp as operands
x1 = Fxp(-7.25, signed=True, n_word=16, n_frac=8)
x2 = Fxp(1.5, signed=True, n_word=16, n_frac=8)
x3 = Fxp(-0.5, signed=True, n_word=8, n_frac=7)

y = 2*x1 + x2 - 0.5     # y is a new Fxp object

y = x1*x3 - 3*x2        # y is a new Fxp object, again

If we need to model that the result of a math operation is stored in other fractional fixed-point variable with a particular format we should do the following:

# variable to store a result
y = Fxp(None, signed=True, n_word=32, n_frac=16)

y.equal(x1*x3 - 3*x2)

At the end, we also have the possibility of get the value of a math operation and set that val in the varible create

View on GitHub
GitHub Stars205
CategoryDevelopment
Updated3d ago
Forks25

Languages

Python

Security Score

100/100

Audited on Mar 24, 2026

No findings