require "big" def pow10(exp : Int32) : BigInt result = BigInt.new(1) exp.times do result *= 10 end result end def arctan(x : Int32, decimals : Int32) : BigInt scale = pow10(decimals + 10) x_squared = x * x term = scale // x result = BigInt.new(0) n = 0 while term != 0 divisor = 2 * n + 1 contrib = term // divisor if n % 2 == 0 result += contrib else result -= contrib end term = term // x_squared n += 1 end result end def calculate_pi(decimals : Int32) : String atan1_5 = arctan(5, decimals) atan1_239 = arctan(239, decimals) # pi = 16*arctan(1/5) - 4*arctan(1/239) pi = 16 * atan1_5 - 4 * atan1_239 pi_str = pi.to_s # Format with decimal point result = "3." start = 1 decimals.times do |i| if start + i < pi_str.size result += pi_str[start + i].to_s else result += "0" end end result end # Main decimals = ARGV.size > 0 ? ARGV[0].to_i? || 100 : 100 puts calculate_pi(decimals)