floating-point - 我应该如何处理 float ,这些数字可以变得如此之小以至于变成零

标签 floating-point numerical-methods

所以我只是在下面的代码中修复了一个有趣的错误,但我不确定我采用的最好的方法:

p = 1
probabilities = [ ... ] # a (possibly) long list of numbers between 0 and 1
for wp in probabilities:

  if (wp > 0):
    p *= wp

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up
# being zero
try:
    result = math.log(p)

因为结果不需要精确,我通过简单地保留最小的非零值来解决这个问题,并在 p 变为 0 时使用它。
p = 1
probabilities = [ ... ] # a long list of numbers between 0 and 1
for wp in probabilities:

  if (wp > 0):
    old_p = p
    p *= wp
    if p == 0:
      # we've gotten so small, its just 0, so go back to the smallest
      # non-zero we had
      p = old_p
      break

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up
# being zero
try:
    result = math.log(p)

这有效,但对我来说似乎有点笨拙。我不做大量的这种数值编程,我不确定这是否是人们使用的那种修复,或者是否有更好的东西我可以去。

最佳答案

从,math.log(a * b)等于 math.log(a) + math.log(b) ,为什么不把probabilities的所有成员的日志求和?大批?

这样就避免了p的问题变得如此之小以至于流量不足。

编辑:这是 numpy 版本,对于大型数据集,它更干净且速度更快:

import numpy
prob = numpy.array([0.1, 0.213, 0.001, 0.98 ... ])
result = sum(numpy.log(prob))

关于floating-point - 我应该如何处理 float ,这些数字可以变得如此之小以至于变成零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2999853/

相关文章:

matlab - 解决超定约束系统

java - long值如何适应Java中的float数据类型而不损失精度

visual-c++ - 比较两个 double 的符号

OpenGL纹理坐标和小 float 的精度

numpy - numpy.var 中的精度错误

r - 哪些数值优化器可以只使用梯度,而没有明确的目标值?

vector - 在 Common Lisp 中计算向量的线性组合

c - 意外结果,因为浮点减法变为 -0.0 和 +0.0

c# - 为什么 float.Parse ("123,45") 不抛出异常

c - 简谐振子的改进欧拉法