fxpmath :将两个无符号数减去有符号数

问题描述 投票:0回答:1
import numpy as np
from fxpmath import Fxp as fxp

t1 = fxp(4, False, 9, 3)
t2 = fxp(5, False, 9, 3)
inter1 = fxp(0, True, 9, 3, raw=True)
inter2 = fxp(0, True, 9, 3, raw=True)

inter1(t1 - t2)
inter2(t1.get_val() - t2.get_val())

inter1 等于 0.00,因为计算中使用的两个数字都是无符号的。我发现获得正确结果的唯一方法是使用 numpy 值(来自 get_val())。有没有最好的方法来做到这一点?我不想将 t1 或 t2 带符号。

python data-conversion fixed-point
1个回答
0
投票

@jasonharper 提出的解决方案是正确的,但它可能不是您想要建模的。

当你这样做时:

t1.like(inter1) - t2.like(inter1) # t1_signed - t2_signed

fxp-s10/3(-1.0)

您正在将

t1
t2
转换为 signed 就像
inter1
一样,所以您正在执行 signed 减法,我认为这不是您想要建模的。

无符号 fxp 转换为有符号,将 msb(最高有效位)强制转换为

0
(如果保持大小)。如果
t1
和/或
t2
等于或大于 有符号上限(对于您的示例为 31.875),这将生成错误的计算。例如:

t3 = fxp(48, False, 9, 3)
t4 = fxp(49, False, 9, 3)

t3.like(inter1) - t4.like(inter1) # t3_signed - t4_signed
# t3_signed = fxp-s9/3(31.875) because overflow clipping
# t4_signed = fxp-s9/3(31.875) because overflow clipping

fxp-s10/3(0.0)

如果您尝试建模无符号减法,然后将该值存储在有符号 fxp 中,则必须使用wrap 溢出。另外,如果你想将大小保持在减法(或其他操作),你必须设置

op_sizing = 'same'

t1 = fxp(4, False, 9, 3, overflow='wrap', op_sizing='same')
t2 = fxp(5, False, 9, 3, overflow='wrap', op_sizing='same')

t1 - t2

fxp-u9/3(63.0)

如果你检查二进制格式,你会发现减法是正确的:

(t1 - t2).bin(frac_dot=True)

'111111.000'

msb 等于

1
,因此当您将此值转换为 signed fxp 时,这将是负值:

# cast from unsigned to signed keeping raw binary value
inter1('0b' + (t1 - t2).bin(frac_dot=True)) 

fxp-s9/3(-1.0)

现在,

t3 = fxp(48, False, 9, 3, overflow='wrap', op_sizing='same')
t4 = fxp(49, False, 9, 3, overflow='wrap', op_sizing='same')
inter1('0b' + (t3 - t4).bin(frac_dot=True))

fxp-s9/3(-1.0)

最后,让我编写一种更优雅的方法来在代码中使用相同的 fxp 大小:

from fxpmath import Fxp

# Set a template for new Fxp objects
Fxp.template = Fxp(dtype='fxp-u9/3', overflow='wrap', op_sizing='same')

inter1 = Fxp(None, signed=True) # overwrite template's sign

t1 = Fxp(4)
t2 = Fxp(5)
inter1('0b' + (t1 - t2).bin(True)) # or inter1('0b' + (Fxp(4) - Fxp(5)).bin(True))

fxp-s9/3(-1.0)

© www.soinside.com 2019 - 2024. All rights reserved.