diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | lib/mathn.rb | 104 |
2 files changed, 100 insertions, 9 deletions
@@ -1,3 +1,8 @@ +Mon May 23 09:08:07 2011 Eric Hodel <drbrain@segment7.net> + + * lib/mathn.rb: Improve documentation. Patch by Sandor Szucs. + [Ruby 1.9 - Bug #4767] + Mon May 23 08:45:55 2011 Eric Hodel <drbrain@segment7.net> * lib/ostruct.rb: Improve documentation. Patch by Franklin Webber. diff --git a/lib/mathn.rb b/lib/mathn.rb index 61de1ff9ac..05840924d9 100644 --- a/lib/mathn.rb +++ b/lib/mathn.rb @@ -1,7 +1,22 @@ ## # = mathn # -# mathn is a library for changing the way Ruby does math. +# mathn is a library for changing the way Ruby does math. If you need +# more precise rounding with multiple division or exponentiation +# operations, then mathn is the right tool. It makes sense to use this +# library if you can use it's late rounding. Mathn does not convert +# Fixnums into Floats as long as you do not convert it yourself. +# Instead of using Float as intermediate value it use Rational as +# value representation. +# +# Example Fixnum with intermediate Float: +# +# 20 / 9 * 3 * 14 / 7 * 3 / 2 # => 18 +# +# Example: using mathn Fixnum/Rational: +# +# require 'mathn' +# 20 / 9 * 3 * 14 / 7 * 3 / 2 # => 20 # # == Usage # @@ -13,13 +28,13 @@ # # 3 / 2 # -# will return (3/2) instead of the usual 1. +# will return +Rational+ (3/2) instead of the usual +Fixnum+ 1. # # == Copyright # # Author: Keiju ISHITSUKA(SHL Japan Inc.) # -# -- +#-- # $Release Version: 0.5 $ # $Revision: 1.1.1.1.4.1 $ @@ -35,14 +50,29 @@ unless defined?(Math.exp!) Math = CMath end +## +# When mathn is required Fixnum's division and exponentiation are enhanced to +# return more precise values in mathematical formulas. +# +# 2/3*3 # => 0 +# require 'mathn' +# 2/3*3 # => 2 + class Fixnum remove_method :/ + + ## + # +/+ defines the Rational division for Fixnum. + # + # 1/3 # => (1/3) + alias / quo alias power! ** unless method_defined? :power! ## - # exponentiate by +other+ + # Exponentiate by +other+ + def ** (other) if self < 0 && other.round != other Complex(self, 0.0) ** other @@ -53,14 +83,25 @@ class Fixnum end +## +# When mathn is required Bignum's division and exponentiation are enhanced to +# return more precise values in mathematical formulas. + class Bignum remove_method :/ + + ## + # +/+ defines the Rational division for Bignum. + # + # (2**72) / ((2**70) * 3) # => 4/3 + alias / quo alias power! ** unless method_defined? :power! ## - # exponentiate by +other+ + # Exponentiate by +other+ + def ** (other) if self < 0 && other.round != other Complex(self, 0.0) ** other @@ -71,11 +112,27 @@ class Bignum end +## +# When mathn is required Rational changes to simplfy the usage of Rational +# operations. +# +# Normal behaviour: +# +# Rational.new!(1,3) ** 2 # => Rational(1, 9) +# (1 / 3) ** 2 # => 0 +# +# require 'mathn' behaviour: +# +# (1 / 3) ** 2 # => 1/9 + class Rational remove_method :** ## - # exponentiate by +other+ + # Exponentiate by +other+ + # + # (1/3) ** 2 # => 1/9 + def ** (other) if other.kind_of?(Rational) other2 = other @@ -138,11 +195,32 @@ class Rational end end +## +# When mathn is requried the Math module changes as follows: +# +# Standard Math module behaviour: +# Math.sqrt(4/9) # => 0.0 +# Math.sqrt(4.0/9.0) # => 0.666666666666667 +# Math.sqrt(- 4/9) # => Errno::EDOM: Numerical argument out of domain - sqrt +# +# After require 'mathn' this is changed to: +# +# require 'mathn' +# Math.sqrt(4/9) # => 2/3 +# Math.sqrt(4.0/9.0) # => 0.666666666666667 +# Math.sqrt(- 4/9) # => Complex(0, 2/3) + module Math remove_method(:sqrt) ## - # compute the square root of +a+ + # Computes the square root of +a+. It makes use of Complex and + # Rational to have no rounding errors if possible. + # + # Math.sqrt(4/9) # => 2/3 + # Math.sqrt(- 4/9) # => Complex(0, 2/3) + # Math.sqrt(4.0/9.0) # => 0.666666666666667 + def sqrt(a) if a.kind_of?(Complex) abs = sqrt(a.real*a.real + a.imag*a.imag) @@ -168,7 +246,11 @@ module Math end end - def rsqrt(a) # :nodoc: + ## + # Compute square root of a non negative number. This method is + # internally used by +Math.sqrt+. + + def rsqrt(a) if a.kind_of?(Float) sqrt!(a) elsif a.kind_of?(Rational) @@ -220,11 +302,15 @@ module Math module_function :rsqrt end +## +# When mathn is required Float is changed to handle Complex numbers. + class Float alias power! ** ## - # exponentiate by +other+ + # Exponentiate by +other+ + def ** (other) if self < 0 && other.round != other Complex(self, 0.0) ** other |