bigdecimal
bigdecimal copied to clipboard
BigMath methods returns inaccurate value for rational
Because Rational is simply converted to BigDecimal with the given precision. Precision is not that simple. Though it may not be a responsibility for BigMath.
BigMath.exp: Maximum 19 digits precision loss
BigMath.exp(10**19/3r, 50).to_s[0,52]
#=> "0.31897971307307432918427098497346266668405585204999"
BigMath.exp(10**19/3r, 1000).to_s[0,52]
#=> "0.31897971307307432918427098497347329934115828786096"
BigMath.log: Many precision loss near x=1
BigMath.log(1+1r/12345**9, 50)
#=> 0.15016895257719999999999999999999999998872464284093e-36
BigMath.log(1+1r/12345**9, 1000).mult(1, 50)
#=> 0.1501689525772244244950394251097065861542145195459e-36
BigMath.sin: Many precision loss near x=n*π
x = (31415926535897932384626433832795 * 7 + 1).quo(7 * 10**40)
BigMath.sin(x, 50)
#=> 0.26542232205820974944592307816406286208998628034825e-40
BigMath.sin(x, 1000).mult(1, 50)
#=> 0.26542232248678117801735164959263429066141485177682e-40
Each method requires different Rational to BigDecimal conversion. For example:
- log:
x < 1/2r ? BigDecimal(x, prec) : BigDecimal(x - 1, prec) + 1 - exp:
BigDecimal(x, prec + [BigDecimal(x, 1).exponent, 0].max) - sqrt: Nothing special.
BigDecimal(x, prec) - sin, cos: Needs precision increasing loop