I have to get the exact amount of decimal digits of pi, so I tried using this method:
require "bigdecimal/math"
include BigMath
input = 9
output = BigMath.PI(input).to_s
puts output
but instead of getting this as a result:
output: 3.141592653 # Which are the first 9 decimal digits of PI
I get this:
output: 0.3141592653589793238462643313830947690870926e1
What am I doing wrong?
Since π is an irrational number, its decimal representation never ends and never settles into a permanently repeating pattern.
Therefore, algorithms for calculation of π can find only results with specified precision.
BigMath.PI
- is not an exception.
Parameter prec
which we pass as a first argument, means precision (that is the number of accurate digits after the decimal point).
When we execute BigMath.PI(9)
, we obtain a BigDecimal
instance, which string representation is 0.3141592653589793238462643313830947690870926e1
.
If we look more closely at this string we can see e1
in the end.
Such notation is common in math and it means:
Hence, in our case
0.3141592653589793238462643313830947690870926e1
is the same as
0.3141592653589793238462643313830947690870926 * 10 = 3.141592653589793238462643313830947690870926
Since we passed 9
to BigMath.PI
, we have at least 9 accurate digits after the decimal dot
3.141592653589793238462643313830947690870926
3.141592653_________________________________
(Actually, when we pass 9
to BigMath.PI
, it returns more than 9 accurate digits after the decimal dot, but we should not rely on this fact. You can try to compare if you like).
And probably the last thing to mention: we can't just convert BigDecimal
to Float
, if we care about accuracy, because Float
in general stores only 15 digits after the decimal dot.
So, if your goal is to be able to show π with an arbitrary number of digits after the decimal dot, you can use the following method:
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
If not, then, please, update your question to make it less ambiguous.