我必须获得pi的精确十进制数字,所以我尝试使用此方法:
require "bigdecimal/math"
include BigMath
input = 9
output = BigMath.PI(input).to_s
puts output
而不是得到结果:
output: 3.141592653 # Which are the first 9 decimal digits of PI
我明白了:
output: 0.3141592653589793238462643313830947690870926e1
我在做什么错了?
答案 0 :(得分:1)
由于π是irrational number,所以它的decimal representation never ends and never settles into a permanently repeating pattern。
因此,algorithms for calculation of π只能找到指定精度的结果。
BigMath.PI
-也不例外。
我们作为第一个参数传递的参数prec
表示精度(即小数点后的精确位数)。
执行BigMath.PI(9)
时,我们获得一个BigDecimal
实例,其字符串表示形式为0.3141592653589793238462643313830947690870926e1
。
如果我们仔细看一下这个字符串,我们可以最后看到e1
。
Such notation在数学中很常见,这意味着:
因此,在我们的情况下
0.3141592653589793238462643313830947690870926e1
与
相同0.3141592653589793238462643313830947690870926 * 10 = 3.141592653589793238462643313830947690870926
自从9
传递到BigMath.PI
以来,我们在小数点后有at least 9 accurate digits
3.141592653589793238462643313830947690870926
3.141592653_________________________________
(实际上,当我们将9
传递给BigMath.PI
时,它会返回小数点后9个以上的准确数字,但是我们不应该依赖这个事实。如果有以下情况,可以使用try to compare你喜欢)。
也许还有最后一件事要提到:如果我们关心准确性,我们不能仅将BigDecimal
转换为Float
,因为Float
通常只在小数点后存储15位数字点。
因此,如果您的目标是能够在小数点后显示π,且位数为任意位数,则可以使用以下方法:
require 'bigdecimal/math'
##
# Returns PI as a string with number_of_digits_after_decimal_dot.
#
def pi(number_of_digits_after_decimal_dot: 2)
# Let's assume presicion equals to 2 as an example
precision = number_of_digits_after_decimal_dot
result = BigMath.PI(precision)
# => ВigDecimal 0.31415926535897932384671233672993238432e1
result = result.truncate(precision).to_s
# => String 0.314e1
# Remove '0.'
result = result[2..-1]
# => String 3141e1
# Remove 'e1'
result = result.split('e').first
# => String 3141
result = result.insert(1, '.')
# => String 3.141
result
end
(可以在here中找到规格)。
如果没有,请更新您的问题,以减少歧义。