我有两个分数列表;
说A = [ 1/212, 5/212, 3/212, ... ]
和B = [ 4/143, 7/143, 2/143, ... ]
。
如果我们定义A' = a[0] * a[1] * a[2] * ...
和B' = b[0] * b[1] * b[2] * ...
我想计算A'和B'的归一化值
即特别是A' / (A'+B')
和B' / (A'+B')
的值
我的麻烦是A和B都很长而且每个值都很小,因此计算乘积会很快导致数值下溢...
我知道通过对数将乘积求和可以帮助我确定A'或B'中哪个更大
即max( log(a[0])+log(a[1])+..., log(b[0])+log(b[1])+... )
并且使用日志我可以计算A' / B'
的值,但是我该怎么做A' / A'+B'
迄今为止,我最好的选择是将数字表示形式保留为小数,即A = [ [1,212], [5,212], [3,212], ... ]
并实现我自己的算术,但是它变得笨拙,我觉得我有一种(简单)对数的方法,我只是想念...。
A和B的分子不是来自序列。对于这个问题,它们也可能是随机的。如果有帮助,则A中所有值的分母都一样,B中所有分母都一样。
任何想法最欢迎!
(PS。我在24小时前询问了A'/B'
比率,但这实际上是一个错误的问题。我实际上是在A'/(A'+B')
之后。很抱歉,我的错。)
最佳答案
我在这里看不到什么办法
首先,您会注意到
A' / (A'+B') = 1 / (1 + B'/A')
而且您知道如何使用对数计算
B'/A'
。另一种方法是实现自己的有理算术,但您无需花太多时间。由于您知道整个数组的分母是相同的,因此它立即为您提供了
numerator(A') = numerator(a[0]) * numerator(a[1]) ...
denumerator(A') = denumerator(a[0]) ^ A.length
您现在要做的就是将简单的A'和B'相加,然后将
A'
和1/(A'+B')
相乘也很容易。这里最难的部分是对结果值进行归一化,这是通过模运算完成的,并且是微不足道的。另外,由于您最有可能使用某些流行的脚本语言,因此它们中大多数都内置了用于理性算术的类,因此Python和Ruby肯定会使用它们。