如何计算 Ruby 中的圆周率?
How to calculate PI in Ruby?
我必须得到圆周率的精确小数位数,所以我尝试使用这个方法:
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
我做错了什么?
因为 π 是 irrational number, its 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
时,它returns小数点后多了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
如果不是,那么请更新您的问题以减少歧义。
我必须得到圆周率的精确小数位数,所以我尝试使用这个方法:
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
我做错了什么?
因为 π 是 irrational number, its 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
时,它returns小数点后多了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
如果不是,那么请更新您的问题以减少歧义。