ruby精确数字日志(对数)函数

ruby精确数字日志(对数)函数,ruby,logarithm,Ruby,Logarithm,由于1000以10为底的对数是3,您可能希望Math::log(1000,10)返回3。相反,它返回2.999999999999 6 这是因为Ruby中的浮点数不是所讨论的精确数字,例如: 浮点数不是一个精确的数字表示形式,如下所述: 浮点对象使用本机体系结构的双精度浮点表示来表示不精确的实数 这不是ruby错误,因为浮动只能由固定的 字节数,因此无法正确存储十进制数 或者,您可以使用ruby或 不幸的是,当调用Math::log(BigDecimal('1000')、BigDecimal('1

由于1000以10为底的对数是3,您可能希望
Math::log(1000,10)
返回
3
。相反,它返回
2.999999999999 6

这是因为Ruby中的浮点数不是所讨论的精确数字,例如:

浮点数不是一个精确的数字表示形式,如下所述:

浮点对象使用本机体系结构的双精度浮点表示来表示不精确的实数

这不是ruby错误,因为浮动只能由固定的 字节数,因此无法正确存储十进制数

或者,您可以使用ruby或

不幸的是,当调用
Math::log(BigDecimal('1000')、BigDecimal('10'))
时,结果完全相同。同样适用于
Math::log(Rational('1000')、Rational('10'))
。还有一个
BigMath::log
,它

现在最大的问题是:我们如何计算以10为底的1000的对数,从而得到准确的结果:
3

你可以使用:如果你可以计算以d为底的对数,但是你需要以b为底的对数,那么
log\u b(n)=log\u d(n)/log\u d(b)
。因此:

> BigMath.log(1000, 50) / BigMath.log(10, 50)
=> 0.3e1
现在,让我们尝试一些需要更精确的方法:

> BigMath.log(999, 50) / BigMath.log(10, 50)
=> 0.2999565488225982308693534399304475375583359282738400141107276831709276456467950527020061473296516829369378125e1

与之相比,比如说,您在这里遇到了浮点数的限制,但是值
2.999999999999 6
显示16位小数(不可靠)精度

要恢复到可靠的精度,请将四舍五入到小数点后15位:

>> Math::log(1000, 10)
=> 2.9999999999999996
>> Math::log(1000, 10).round(15)
=> 3.0

双精度的C语言规范,因此Ruby实现可能会有小于15位有效小数的浮点s,但在“Ruby bigdecimal log”上搜索web时,更常见的是看到15位有效小数。

我发现没有多少是相关的,至少在撰写本文的时候没有。所以我希望这个关于stackoverflow的问题能够填补这个空白。更重要的是,当它伴随着一个实际的答案:-)嗯,令人惊讶的是Math::log10(1000)返回3.0您可以在这里查看源代码和文档:。我仍在努力了解实施情况