1 
1 
##

2 
2 
# = mathn

3 
3 
#

4 

# mathn is a library for changing the way Ruby does math.


4 
# mathn is a library for changing the way Ruby does math. If you need


5 
# more precise rounding with multiple division or exponentiation


6 
# operations, then mathn is the right tool. It makes sense to use this


7 
# library if you can use it's late rounding. Mathn does not convert


8 
# Fixnums into Floats as long as you do not convert it yourself.


9 
# Instead of using Float as intermediate value it use Rational as


10 
# value representation.


11 
#


12 
# Example Fixnum with intermediate Float:


13 
#


14 
# 20 / 9 * 3 * 14 / 7 * 3 / 2 #=> 18


15 
#


16 
# Example: using mathn Fixnum/Rational:


17 
#


18 
# require 'mathn'


19 
# 20 / 9 * 3 * 14 / 7 * 3 / 2 #=> 20

5 
20 
#

6 
21 
# == Usage

7 
22 
#

...  ...  
13 
28 
#

14 
29 
# 3 / 2

15 
30 
#

16 

# will return (3/2) instead of the usual 1.


31 
# will return +Rational+ (3/2) instead of the usual +Fixnum+ 1.

17 
32 
#

18 
33 
# == Copyright

19 
34 
#

...  ...  
35 
50 
Math = CMath

36 
51 
end

37 
52 


53 
##


54 
# Fixnum's division and exponentiation are enhanced to return more


55 
# precise values in mathematical formulas.


56 
#


57 
# 2/3*3 #=> 0


58 
# require 'mathn'


59 
# 2/3*3 #=> 2


60 
#

38 
61 
class Fixnum

39 
62 
remove_method :/


63 
##


64 
# +/+ defines the Rational division for Fixnum.


65 
#


66 
# 1/3 #=> (1/3)


67 
#

40 
68 
alias / quo

41 
69 

42 
70 
alias power! ** unless method_defined? :power!

...  ...  
53 
81 

54 
82 
end

55 
83 


84 
# Bignum's division and exponentiation are enhanced to return more


85 
# precise values in mathematical formulas.

56 
86 
class Bignum

57 
87 
remove_method :/


88 
##


89 
# +/+ defines the Rational division for Bignum.


90 
#


91 
# (2**72) / ((2**70) * 3) #=> 4/3


92 
#

58 
93 
alias / quo

59 
94 

60 
95 
alias power! ** unless method_defined? :power!

...  ...  
71 
106 

72 
107 
end

73 
108 


109 
##


110 
# Rational changes that simplfies the usage of Rational opaerations.


111 
#


112 
# normal behaviour:


113 
#


114 
# Rational.new!(1,3) ** 2 #=> Rational(1, 9)


115 
# (1 / 3) ** 2 #=> 0


116 
#


117 
# mathn behaviour:


118 
#


119 
# (1 / 3) ** 2 #=> 1/9


120 
#

74 
121 
class Rational

75 
122 
remove_method :**

76 
123 

77 
124 
##

78 
125 
# exponentiate by +other+


126 
#


127 
# (1/3) ** 2 #=> 1/9


128 
#

79 
129 
def ** (other)

80 
130 
if other.kind_of?(Rational)

81 
131 
other2 = other

...  ...  
138 
188 
end

139 
189 
end

140 
190 


191 
##


192 
# Changes of the ruby Math module.


193 
#


194 
# standard Math module behaviour:


195 
# Math.sqrt(4/9) #=> 0.0


196 
# Math.sqrt(4.0/9.0) #=> 0.666666666666667


197 
# Math.sqrt( 4/9) #=> Errno::EDOM: Numerical argument out of domain  sqrt


198 
#


199 
# using mathn library this is changed to:


200 
# require 'mathn'


201 
# Math.sqrt(4/9) #=> 2/3


202 
# Math.sqrt(4.0/9.0) #=> 0.666666666666667


203 
# Math.sqrt( 4/9) #=> Complex(0, 2/3)


204 
#

141 
205 
module Math

142 
206 
remove_method(:sqrt)

143 
207 

144 
208 
##

145 

# compute the square root of +a+


209 
# Compute the square root of +a+. It makes use of Complex and


210 
# Rational to have no rounding errors if possible.


211 
#


212 
# Math.sqrt(4/9) #=> 2/3


213 
# Math.sqrt( 4/9) #=> Complex(0, 2/3)


214 
# Math.sqrt(4.0/9.0) #=> 0.666666666666667

146 
215 
def sqrt(a)

147 
216 
if a.kind_of?(Complex)

148 
217 
abs = sqrt(a.real*a.real + a.imag*a.imag)

...  ...  
168 
237 
end

169 
238 
end

170 
239 

171 

def rsqrt(a) # :nodoc:


240 
# Compute square root of a non negative number. This method is


241 
# internally used by +Math.sqrt+.


242 
def rsqrt(a)

172 
243 
if a.kind_of?(Float)

173 
244 
sqrt!(a)

174 
245 
elsif a.kind_of?(Rational)

...  ...  
220 
291 
module_function :rsqrt

221 
292 
end

222 
293 


294 
##


295 
# Float is changed to know Complex numbers.

223 
296 
class Float

224 
297 
alias power! **

225 
298 

226 


