I need a function to convert a float number to a fixed-point number, represented in binary so that I can put it to the hardware accelerator which can only accept fix-point number. for example, when I input a float number 5.625, giving data width 8, precision 4(4 bits for mantissa), it will return b'01011010, or h'5a or d'90. Is there any functions like this in python libraries?
Asked
Active
Viewed 5,032 times
1
-
1Try the built-in `Decimal` module: https://docs.python.org/3.5/library/decimal.html – Vasili Syrakis Jan 11 '17 at 11:46
-
see http://stackoverflow.com/questions/422247/fixed-point-arithmetic – kennytm Jan 11 '17 at 11:54
5 Answers
4
That's the same as multiplying by 16 and converting to an int.
>>> int(5.625 * (2 ** 4))
90
The 16 depends on the number of bits in the precision, but it's easily calculated.
If the number has to go in multiple bytes (like 2 or 4), use the struct
module. E.g. for 300.625 with 32 data bits, 8 of which are precision:
>>> int(300.625 * (2**8))
76960
>>> struct.pack('I', 76960) # 'I' is 4-byte unsigned int
b'\xaa,\x01\x00'

RemcoGerlich
- 30,470
- 6
- 61
- 79
-
On this site, show your appreciation by upvoting all the useful answers. You do that by clicking the up-arrow at the top-left of the answer. In addition, accept the best answer (if it actually answers your question) by clicking the checkmark near the top-left of the answer. That is better than saying thanks in a comment. It also helps others to see that your question was answered. – Rory Daulton Jan 11 '17 at 13:02
1
You can use fxpmath in python. You can find info about it at:
https://github.com/francof2a/fxpmath
In your example case:
from fxpmath import Fxp
x = Fxp(5.625, signed=False, n_word=8, n_frac=4)
print(x) # float value
print(x.bin()) # binary representation
print(x.hex()) # hex repr
print(x.val) # raw val (decimal of binary stored)
Outputs:
5.625
01011010
0x5a
90

francof2a
- 154
- 4
1
several fixed point libraries like numfi can transform floating point number to fixed point and give bin/dec/hex representation
>>> from numfi import numfi
>>> x = numfi(5.625,1,8,4)
>>> x.int # d'90
array([90], dtype=int64)
>>> x.bin # b'01011010
array(['01011010'], dtype='<U8')
>>> x.hex # h'5a
array(['5A'], dtype='<U2')
If you prefer simpler solution, you can do quantization yourself:
num = 5.625
w = 8 # data width
f = 4 # fraction width
quantized = np.round(num*(2**f)).astype(int) #note: overflow is not considered here
dec_repr = np.base_repr(quantized, base=10)
bin_repr = np.binary_repr(quantized, width=8)
hex_repr = np.base_repr(quantized, base=16)

ZinGer_KyoN
- 89
- 5
0
Try to use decimal module.
You may pass it a float formatted as a string with required format and precision:
>>> from decimal import Decimal
>>> '{:5f}'.format(10.0)
'10.000000'
>>> Decimal('{:5f}'.format(10.0))
Decimal('10.000000')

Eugene Lisitsky
- 12,113
- 5
- 38
- 59
-
-
As a way to prepare to real format. Next step tweak to topic starter format with Decimal Contexts. – Eugene Lisitsky Jan 11 '17 at 12:29
-
But the precision you can set with decimal context is in number of base-10 digits, it never maps exactly to a number of bits. – RemcoGerlich Jan 11 '17 at 12:32
0
def float2fix(val, width, precision):
integer = abs(int(val * 2 ** precision))
if val < 0:
integer = 2 ** (width-1) - integer
if val >= 0:
fix_str = bin(integer).replace('0b', '').rjust(width, '0')
else:
fix_str = '1'+bin(integer).replace('0b', '').rjust(width-1, '0')
return fix_str

bander zhang
- 21
- 1
- 3