fxpmath icon indicating copy to clipboard operation
fxpmath copied to clipboard

Reversal of .bin()

Open nfrancque opened this issue 4 years ago • 5 comments

I'm wondering if there is a way to revert calling .bin(). Something like:

x1 = Fxp(3.4)
x_bin = x1.bin()
x2 = from_bin(x_bin)
assert x1 == x2

My use case is to convert into the notation, do some operations, then convert the result back over. I see the constructor can take in a binary value but it looks like it only takes in a "normal" python bit string. Is this possible currently?

nfrancque avatar Dec 22 '21 20:12 nfrancque

The method bin returns a string without 0b prefix to maintain compatibility with python. So, you can add this prefix before create a new Fxp or when you get binary string, taking into account that you need to specify the fractional format. I can give you some examples to solve that:

x1 = Fxp(3.4)
x_bin = x1.bin() # or '0b' + x1.bin()
x2 = Fxp('0b' + x_bin, like=x1) # also works with fractional dot format

If you don't want to keep x1 you should create Fxp with a particular dtype or work with a fractional binary string format:

x1 = Fxp(3.4)
x_bin = x1.bin(frac_dot=True)
x2 = Fxp('0b' + x_bin)

In the last example x2 could have a different size than x1 because leading or trailing zeros.

francof2a avatar Dec 22 '21 20:12 francof2a

Thanks for the quick response. The first example works in my case since the original will still be around so I'll go with that. It'd be a nice enhancement to go from just the output string on its own (as long as frac_dot was specified) back to an Fxp with a guarantee that they are the same sizes.

nfrancque avatar Dec 23 '21 13:12 nfrancque

Yes, it would be good! I'll try to include that in next release. Thanks for the recommendation.

francof2a avatar Dec 23 '21 20:12 francof2a

Hi @francof2a ,

I am facing issue with fraction part using above method.

float_val = 256.2
ret_int = Fxp(float_val, n_word=32, signed=True, n_frac=2, n_int=29,)
ret_float = Fxp("0b"+ ret_int.bin(),  n_word=32, signed=True, n_frac=2, n_int=29,)
print(ret_float)

output is 256 but I need 256.2

kokare-darshan avatar Feb 02 '22 16:02 kokare-darshan

As you are using 2 bits for fractional part, 256.2 is rounded to 256.0. You need more fractional bits to get a fixed-point value closer to 256.2.

With 2 bits for fractional part, the closer values to 256.2 are 256.0 and 256.25. If you use rounding='ceil' or rounding='around', you will get a fixed-point value of 256.25 instead of 256.0.

ret_int = Fxp(float_val, n_word=32, signed=True, n_frac=2, n_int=29, rounding='ceil')

If you fix the n_word size to 32 but let to Fxp finds the best fractional part:

ret_int = Fxp(float_val, n_word=32, signed=True)

fxp-s32/22(256.19999980926514)

francof2a avatar Feb 14 '22 16:02 francof2a

solved in v0.4.9

francof2a avatar Feb 08 '24 01:02 francof2a