tgamma计算结果过快变为无穷大,如何实现更高数值的存储?
问题解决方法
你不需要追求存储更大的数值,换用对数伽马函数计算即可从根本上避免溢出问题:
你最终需要的结果是三个伽马函数的比值gamma(a+b)/(gamma(a)*gamma(b)),等价于计算exp(lgamma(a+b) - lgamma(a) - lgamma(b))。绝大多数编程语言的标准数学库都提供lgamma函数(返回伽马函数的自然对数值),修改后的代码如下:
let log_x = lgamma(a+b) let log_y = lgamma(a) let log_z = lgamma(b) let norm = exp(log_x - log_y - log_z)
方案说明
- 伽马函数本身增长速度极快,即使用64位双精度浮点数存储,输入参数大于171时结果就会超出最大可表示范围变为无穷大;而对数伽马函数增长非常平缓,输入参数到数千量级都不会溢出
- 在对数域做加减运算后再取指数,和原计算逻辑完全等价,同时还能避免中间步骤的精度损失
- 如果确实需要存储更大的浮点数,可以换用128位长双精度类型(如C语言的
long double、Rust的f128等),但该方案提升上限非常有限,还会带来额外的性能损耗,远不如对数域计算的方案通用高效
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

