我有一堆浮点数(Java 双精度数),其中大部分非常接近 1,我需要将它们相乘作为更大计算的一部分。我需要做很多。
问题是,虽然 Java 的双打对像这样的数字没有问题:
0.0000000000000000000000000000000001 (1.0E-34)
他们不能代表类似的东西:
1.0000000000000000000000000000000001
因此,我迅速失去了精度(Java 的双打的限制似乎在 1.000000000000001 左右)。
我考虑过只存储减去 1 的数字,因此例如 1.0001 将存储为 0.0001 - 但问题是再次将它们相乘我必须加 1,此时我失去了精度。
为了解决这个问题,我可以使用 BigDecimals 来执行计算(转换为 BigDecimal,加 1.0,然后相乘),然后再转换回双精度数,但我非常担心这会对性能产生影响。
任何人都可以看到避免使用 BigDecimal 的方法吗?
为清楚起见进行编辑:这是针对采用梯度下降优化算法的大规模协同过滤器。准确性是一个问题,因为协同过滤器通常处理非常小的数字(例如,一个人点击产品广告的概率,可能是千分之一,或万分之一)。
速度是一个问题,因为协同过滤器必须在数千万个数据点上进行训练,如果不是更多的话。