francof2a / fxpmath

A python library for fractional fixed-point (base 2) arithmetic and binary manipulation with Numpy compatibility.
MIT License
179 stars 21 forks source link

Bug: different results when creating variable with 'like' #88

Closed danilo-bc closed 8 months ago

danilo-bc commented 10 months ago

Variables created using "like" do not result in the same as passing all arguments manually.

Example:

a = Fxp(complex(-0.19165039062500017,-0.33194821385292195), n_word=23, n_int=3, rounding='floor', overflow='saturate')
b = Fxp(complex(-0.19165039062500017,-0.33194821385292195)).like(a)

This results in:

>>> a
fxp-s23/19-complex((-0.1916522979736328-0.33194923400878906j))
>>> b
fxp-s23/19-complex((-0.191650390625-0.33194923400878906j))
francof2a commented 8 months ago

Hello, In your example there is a misunderstanding about use of like method. When you did

b = Fxp(complex(-0.19165039062500017,-0.33194821385292195)).like(a)

first it's created a new Fxp object with auto sizing and after it is converted into a new Fxp with same a features. So, this is equivalent to:

b = Fxp(complex(-0.19165039062500017,-0.33194821385292195))
b = b.like(a)

In order to prevent that you have some options:

option 1

Using like at initialization:

b = Fxp(complex(-0.19165039062500017,-0.33194821385292195), like=a)

option 2

Using a template to force a predefined Fxp format

Fxp.template = Fxp(None, n_word=23, n_int=3, rounding='floor', overflow='saturate')

a = Fxp(complex(-0.19165039062500017, -0.33194821385292195))
b = Fxp(complex(-0.19165039062500017, -0.33194821385292195))

Fxp.template = None # if you wanna disable template since here
danilo-bc commented 8 months ago

Thank you for the comment. This way of creating numbers came from the README, in the "copy" section (https://github.com/francof2a/fxpmath#copy).

There, the form y = Fxp(-1.25).like(x) is said to be equivalent to y = Fxp(-1.25, like=x). Also, the "like template" section uses Fxp objects as templates, and does not show the Fxp.template usage.

# Fxp like templates
DATA        = Fxp(None, True, 24, 15)
ADDERS      = Fxp(None, True, 40, 16)
MULTIPLIERS = Fxp(None, True, 24, 8)
CONSTANTS   = Fxp(None, True, 8, 4)

# init
x1 = Fxp(-3.2).like(DATA)
...

Now that I understand that .like(a) and like=a) operate differently, my problem is solved, but the documentation is confusing.