如果固定和小数部分分开存储,如何将定点数相乘?

问题描述 投票:1回答:2

我想将两个不定分数长度的定点数相乘。定点部分和小数部分分开存储:

123    . 4
fix    . frac
sint32 . sint32

我使用两个变量,一个用于固定部分,一个用于小数部分。

我尝试使用唐津算法。但这仅适用于固定长度的小数。这两个数字的分数部分是变化的。它们可能是相同的,但是对此没有任何保证。当然,最大可能值为(2 ^ 32)-1。

将123.4与56.789相乘的最佳方法是什么?

// a = 123.4
signed int a_fxd = 123;
signed int a_frx = 4;
// b = 56.789
signed int b_fxd = 56
signed int b_frc = 789;
c math addition
2个回答
1
投票

您需要确定小数部分的实际比例因子是多少。对于您的特定示例,看起来合适的因子可能是1/1000或0.001。这意味着56.789表示为56 + 789×0.001。但这意味着123.4将表示为12 + 400×0.001。也就是说,您输入的问题有误:a_frx为400,而不是4。

我不知道Karatsuba's algorithm,而且我怀疑它真的不适用于此问题。我只知道我在小学挣的钱。

让我们用sc表示比例因子。所以我们的乘法实际上是

( a_fxd + a_frx * sc ) * ( b_fxd + b_frx * sc )

乘以这个,我们得到

a_fxd * b_fxd + a_fxd * b_frx * sc + a_frx * b_fxd * sc + a_frx * b_frx * sc * sc

收集术语,我们有

a_fxd * b_fxd + (a_fxd * b_frx + a_frx * b_fxd + a_frx * b_frx * sc) * sc

因此,如果我们将乘积表示为p_fxdp_frx,看起来我们将拥有

p_fxd = a_fxd * b_fxd
p_frx = a_fxd * b_frx + a_frx * b_fxd + a_frx * b_frx * sc

让我们插入实际值:

p_fxd = 123 * 56 = 6888
p_frx = 123 * 789 + 400 * 56 + 400 * 789 * 0.001 = 119762.600

但是还有一个额外的问题,因为p_frx实际上应该是0..999范围内的整数。因此,我们需要丢弃.600并携带119。因此,最终结果是

p_fxd = 6888 + 119 = 7007
p_frx = 762

并且这对应于正确的结果123.4×56.789 = 7007.762。

...实际上,正确正确的结果是7007.7626,或四舍五入为三位数7007.763。因此严格来说,我们不应该丢掉以p_frx结尾的.600,我们应该四舍五入。

当我们考虑负数的可能性时,可能还会有些多余的皱纹需要照顾。

最后,可以选择缩放比例。实际上,我在这里使用的0.001并不是一个现实的值。对于通用算法,您可能会使用诸如1/10000或1/1000000000或1/32768或1/65536之类的东西。 (使用2的幂表示较大的范围,通常可以提高计算效率,但是小数部分的显而易见度不高,十进制表示法之间的转换效率也较低。例如,如果使用比例因子1/32768,则a_frx将为13107,b_frx为25853或25854。)


-1
投票
int a_fxd = 123; int a_frx = 4; int b_fxd = 56; int b_frc = 789;
String a = String.valueOf(a_fxd) +"."+ String.valueOf(a_frx); String b = String.valueOf(b_fxd) + "."+String.valueOf(b_frc); double aDou = Double.valueOf(a); double bDou = Double.valueOf(b); double cDou = aDou * bDou; System.out.print(cDou);
© www.soinside.com 2019 - 2024. All rights reserved.