@@ -28,15 +28,30 @@ function operate!(::typeof(one), x::Rational)
2828end
2929
3030# +
31-
3231function promote_operation (
33- :: typeof (+ ),
32+ :: Union{ typeof(+),typeof(-)} ,
3433 :: Type{Rational{S}} ,
35- :: Type{Rational{T}} ,
34+ :: Type{Rational{T}}
3635) where {S,T}
3736 return Rational{promote_sum_mul (S, T)}
3837end
3938
39+ function promote_operation (
40+ op:: Union{typeof(+),typeof(-)} ,
41+ :: Type{Rational{S}} ,
42+ :: Type{I}
43+ ) where {S,I<: Integer }
44+ return promote_operation (op, Rational{S}, Rational{I})
45+ end
46+
47+ function promote_operation (
48+ op:: Union{typeof(+),typeof(-)} ,
49+ :: Type{I} ,
50+ :: Type{Rational{S}}
51+ ) where {S,I<: Integer }
52+ return promote_operation (op, Rational{S}, Rational{I})
53+ end
54+
4055function operate_to! (output:: Rational , :: typeof (+ ), x:: Rational , y:: Rational )
4156 xd, yd = Base. divgcd (promote (x. den, y. den)... )
4257 # TODO : Use `checked_mul` and `checked_add` like in Base
@@ -46,16 +61,26 @@ function operate_to!(output::Rational, ::typeof(+), x::Rational, y::Rational)
4661 return output
4762end
4863
49- # -
64+ function operate_to! (output:: Rational , :: typeof (+ ), x:: Rational , y:: Integer )
65+ # TODO Use `checked_mul` and `checked_add` like in Base
66+ operate_to! (output. num, * , x. den, y)
67+ operate! (+ , output. num, x. num)
68+ operate_to! (output. den, * , x. den, oftype (x. den, 1 ))
69+ return output
70+ end
5071
51- function promote_operation (
52- :: typeof (- ),
53- :: Type{Rational{S}} ,
54- :: Type{Rational{T}} ,
55- ) where {S,T}
56- return Rational{promote_sum_mul (S, T)}
72+ function operate_to! (output:: Rational , :: typeof (+ ), y:: Integer , x:: Rational )
73+ return operate_to! (output, + , x, y)
5774end
5875
76+ # unary -
77+ function operate_to! (output:: Rational , :: typeof (- ), x:: Rational )
78+ operate_to! (output. num, - , x. num)
79+ operate_to! (output. den, copy, x. den)
80+ return output
81+ end
82+
83+ # binary -
5984function operate_to! (output:: Rational , :: typeof (- ), x:: Rational , y:: Rational )
6085 xd, yd = Base. divgcd (promote (x. den, y. den)... )
6186 # TODO : Use `checked_mul` and `checked_sub` like in Base
@@ -65,6 +90,22 @@ function operate_to!(output::Rational, ::typeof(-), x::Rational, y::Rational)
6590 return output
6691end
6792
93+ function operate_to! (output:: Rational , :: typeof (- ), x:: Rational , y:: Integer )
94+ # TODO Use `checked_mul` and `checked_sub` like in Base
95+ operate_to! (output. num, * , x. den, y)
96+ operate! (- , output. num)
97+ operate! (+ , output. num, x. num)
98+ operate_to! (output. den, copy, x. den)
99+ return output
100+ end
101+
102+ function operate_to! (output:: Rational , :: typeof (- ), y:: Integer , x:: Rational )
103+ # TODO Use `checked_mul` and `checked_sub` like in Base
104+ operate_to! (output, - , x, y)
105+ operate_to! (output, - , output)
106+ return output
107+ end
108+
68109# *
69110
70111function promote_operation (
@@ -75,6 +116,22 @@ function promote_operation(
75116 return Rational{promote_operation (* , S, T)}
76117end
77118
119+ function promote_operation (
120+ :: typeof (* ),
121+ :: Type{Rational{S}} ,
122+ :: Type{I}
123+ ) where {S,I<: Integer }
124+ return promote_operation (* , Rational{S}, Rational{I})
125+ end
126+
127+ function promote_operation (
128+ :: typeof (* ),
129+ :: Type{I} ,
130+ :: Type{Rational{S}}
131+ ) where {S,I<: Integer }
132+ return promote_operation (* , Rational{S}, Rational{I})
133+ end
134+
78135function operate_to! (output:: Rational , :: typeof (* ), x:: Rational , y:: Rational )
79136 xn, yd = Base. divgcd (promote (x. num, y. den)... )
80137 xd, yn = Base. divgcd (promote (x. den, y. num)... )
@@ -83,6 +140,48 @@ function operate_to!(output::Rational, ::typeof(*), x::Rational, y::Rational)
83140 return output
84141end
85142
143+ function operate_to! (output:: Rational , :: typeof (* ), x:: Rational , y:: Integer )
144+ xn = x. num
145+ xd, yn = Base. divgcd (promote (x. den, y)... )
146+ operate_to! (output. num, * , xn, yn)
147+ operate_to! (output. den, copy, x. den)
148+ return output
149+ end
150+
151+ function operate_to! (output:: Rational , :: typeof (* ), y:: Integer , x:: Rational )
152+ return operate_to! (output, * , x, y)
153+ end
154+
155+ # //
156+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Rational , y:: Rational )
157+ xn, yn = Base. divgcd (promote (x. num, y. num)... )
158+ xd, yd = Base. divgcd (promote (x. den, y. den)... )
159+ operate_to! (output. num, * , xn, yd)
160+ operate_to! (output. den, * , xd, yn)
161+ return output
162+ end
163+
164+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Rational , y:: Integer )
165+ xn, yn = Base. divgcd (promote (x. num, y)... )
166+ operate_to! (output. num, copy, xn)
167+ operate_to! (output. den, * , x. den, yn)
168+ return output
169+ end
170+
171+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Integer , y:: Rational )
172+ xn, yd = Base. divgcd (promote (x, y. den)... )
173+ operate_to! (output. num, * , xn, yd)
174+ operate_to! (output. den, copy, y. num)
175+ return output
176+ end
177+
178+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Integer , y:: Integer )
179+ n, d = Base. divgcd (promote (x, y)... )
180+ operate_to! (output. num, copy, n)
181+ operate_to! (output. den, copy, d)
182+ return output
183+ end
184+
86185# gcd
87186
88187function promote_operation (
0 commit comments