我有以下代码:
def pi
pivalue = 4 * (4 * Math.atan(1.0/5.0) - Math.atan(1.0/239.0))
pivaluestring = pi.to_s
puts pivaluestring[0,20]
end
为什么该 pivalue 仅限于小数点后 16 位?我希望有一个更大的限制(最大值)。
使用BigMath和BigDecimal(在标准库中):
require "bigdecimal/math"
p BigMath::PI(50).to_s
#=>"0.3141592653589793238462643383279502884197169399375105820974944592309049629352442819E1"
# Or
include BigMath
p PI(100).to_s
BigDecimal 提供任意精度的浮点十进制算法。
Ruby 浮点数是 64 位浮点数。一旦你去掉符号位和指数位,你就剩下 52 位尾数,大约是 16 位十进制精度。
Ruby 确实有一个任意精度库:大十进制。将您的代码转换为使用它看起来有点像
require "bigdecimal"
require "bigdecimal/math"
def pi(prec=20)
pivalue = 4 * (4 * BigMath.atan(BigDecimal.new("0.2",prec), prec) - BigMath.atan(BigDecimal.new(1)/BigDecimal.new(239), prec))
pivaluestring = pivalue.to_s
puts pivaluestring[0,20]
end
你通常必须给 bigdecimal 一个精度来告诉它必须跟踪多少个小数。
还有一个内置BigMath.PI
函数
那是因为Math.atan
是一个Float
. 由于您在计算过程中只有那么高的精度,因此您无法获得更高的精度。
顺便说一句,对于浮点精度,您只需执行以下操作即可获得 pi:
Math::PI # => 3.141592653589793
基于用于存储值的位数,浮点值的精度有限。阅读这些关于浮点运算和限制的文章: