首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ruby精确数log (对数)函数

ruby精确数log (对数)函数
EN

Stack Overflow用户
提问于 2019-05-29 22:01:53
回答 2查看 404关注 0票数 2

由于基数10为1000的对数为3,所以您可能期望Math::log(1000, 10)返回3。相反,它返回2.9999999999999996

这是因为Ruby中的浮点数并不像讨论的那样精确,例如这里

浮点数不是确切的数字表示形式,如ruby文档中所述: 浮点数对象使用本机架构的双精度浮点表示来表示不精确的实数。这不是红宝石错误,因为浮点数只能用固定的字节数表示,因此不能正确地存储十进制数。 或者,您可以使用ruby 理性BigDecimal

可悲的是,当调用Math::log(BigDecimal('1000'), BigDecimal('10'))时,结果完全相同。Math::log(Rational('1000'), Rational('10'))也是如此。还有一个BigMath::log,它是做些完全不同的事

现在的大问题是:我们如何计算1000的基数10对数,从而得到精确的结果:3

EN

回答 2

Stack Overflow用户

发布于 2019-05-30 00:55:58

您在这里遇到了浮点数的限制。在Ruby中,s通常有15位小数位的精度。,但值2.9999999999999996显示16位小数(不可靠)精度。

为了恢复到可靠的精度,将小数点数圈到15位:

代码语言:javascript
复制
>> Math::log(1000, 10)
=> 2.9999999999999996
>> Math::log(1000, 10).round(15)
=> 3.0

C语言规范10位重要小数点用于double,所以double实现可能会有小于15个小数位的Float,但在这里看到15个重要小数位要常见得多。

票数 4
EN

Stack Overflow用户

发布于 2019-05-30 00:08:42

您可以使用基座公式变化:如果可以使用基本d计算日志,但需要日志基b,则使用log_b(n) = log_d(n) / log_d(b)。所以:

代码语言:javascript
复制
> BigMath.log(1000, 50) / BigMath.log(10, 50)
=> 0.3e1

现在让我们尝试一些需要更精确的东西:

代码语言:javascript
复制
> BigMath.log(999, 50) / BigMath.log(10, 50)
=> 0.2999565488225982308693534399304475375583359282738400141107276831709276456467950527020061473296516829369378125e1

比较一下,比方说,10+999

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56369110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档