我正在计算单词的相对频率(单词数/单词总数)。这会产生相当多的非常小的数字(例如 1.2551539760140076e-05 )。我已经阅读过在这种情况下使用浮点数的一些问题,例如在此article
一个浮点数大约有七位小数的精度......
有人建议使用记录值。我要将这些数字相乘并且想知道
非常感谢任何帮助!
答案 0 :(得分:1)
该文章讨论了C 中的float
类型,它是32位数量。 Python类型float
是一个64位数字,如C double
,因此可以存储大约17个十进制数字(53个小数位而不是24个C float
)。虽然对于某些应用程序来说这也太精确了,但它比32位浮点数要小得多。
此外,因为它是浮点格式,所以1.2551539760140076e-05
(实际上不是那么小)这样的小数字本身并不是不利的。虽然只能表示大约17个十进制数字,但这17个数字不必是小数点后的前17位。它们可以转移,可以说是 1 。实际上,当您将数字作为一组十进制数字乘以十次幂(e-5
)时,您使用了相同的浮动(十进制)点概念。举一个极端的例子,1 -300 可以很好地表示 2 ,10 sup <300> - 只有当这两个数字相遇时,才会出现问题(1e300 + 1e-300 == 1e300
)。
对于日志表示,您可以尽早获取所有值的日志,并在日志空间中执行尽可能多的计算。在您的示例中,您将单词的相对频率计算为log(word_count) - log(total_words)
,这与log(word_count / total_words)
相同,但可能更准确。
如果我不这样做会发生什么不好的事情 - 只是一个不太准确的值或直接错误,例如在乘法?
我不确定区别是什么。数值计算可以具有几乎完美的准确度(相对舍入误差在2 -50 或更好的范围内),但不稳定的算法在某些情况下也会给出可笑的不良结果。每个单独的操作 3 的舍入误差都有相当严格的界限,但是在更长的计算中,它们以惊人的方式相互作用以引起非常大的错误。例如,即使只是总结一大堆浮动也会引入重大错误,特别是如果它们具有非常不同的大小和符号。可靠的数值算法的正确分析和设计是我自己的艺术,我不能在这里公正,但由于IEEE-754的良好设计,大多数算法通常找出好的。不要太担心它,但也不要忽视它。
1 实际上我们正在谈论53个二进制数字被转移,但这对于这个概念来说并不重要。存在十进制浮点格式。
2 相对舍入误差小于2 -54 ,对于分母不是2的幂的任何分数,包括像1/3或0.1
。
3 对于基本算术运算,舍入误差应该是最后一位的半个单位,即必须精确计算结果然后正确舍入。对于超越函数,误差很少超过最后一个或两个单位,但可能更大。