@@ -20,9 +20,18 @@ function operate!(::typeof(one), x::Rational)
2020end
2121
2222# +
23- function promote_operation (:: typeof (+ ), :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
23+ function promote_operation (:: Union{ typeof(+), typeof(-)} , :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
2424 return Rational{promote_sum_mul (S, T)}
2525end
26+
27+ function promote_operation (op:: Union{typeof(+), typeof(-)} , :: Type{Rational{S}} , :: Type{I} ) where {S,I<: Integer }
28+ return promote_operation (op, Rational{S}, Rational{I})
29+ end
30+
31+ function promote_operation (op:: Union{typeof(+), typeof(-)} , :: Type{I} , :: Type{Rational{S}} ) where {S,I<: Integer }
32+ return promote_operation (op, Rational{S}, Rational{I})
33+ end
34+
2635function operate_to! (output:: Rational , :: typeof (+ ), x:: Rational , y:: Rational )
2736 xd, yd = Base. divgcd (promote (x. den, y. den)... )
2837 # TODO Use `checked_mul` and `checked_add` like in Base
@@ -32,10 +41,26 @@ function operate_to!(output::Rational, ::typeof(+), x::Rational, y::Rational)
3241 return output
3342end
3443
35- # -
36- function promote_operation (:: typeof (- ), :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
37- return Rational{promote_sum_mul (S, T)}
44+ function operate_to! (output:: Rational , :: typeof (+ ), x:: Rational , y:: Integer )
45+ # TODO Use `checked_mul` and `checked_add` like in Base
46+ operate_to! (output. num, * , x. den, y)
47+ operate! (+ , output. num, x. num)
48+ operate_to! (output. den, * , x. den, oftype (x. den, 1 ))
49+ return output
50+ end
51+
52+ function operate_to! (output:: Rational , :: typeof (+ ), y:: Integer , x:: Rational )
53+ return operate_to! (output, + , x, y)
3854end
55+
56+ # unary -
57+ function operate_to! (output:: Rational , :: typeof (- ), x:: Rational )
58+ operate_to! (output. num, - , x. num)
59+ operate_to! (output. den, copy, x. den)
60+ return output
61+ end
62+
63+ # binary -
3964function operate_to! (output:: Rational , :: typeof (- ), x:: Rational , y:: Rational )
4065 xd, yd = Base. divgcd (promote (x. den, y. den)... )
4166 # TODO Use `checked_mul` and `checked_sub` like in Base
@@ -45,10 +70,35 @@ function operate_to!(output::Rational, ::typeof(-), x::Rational, y::Rational)
4570 return output
4671end
4772
73+ function operate_to! (output:: Rational , :: typeof (- ), x:: Rational , y:: Integer )
74+ # TODO Use `checked_mul` and `checked_sub` like in Base
75+ operate_to! (output. num, * , x. den, y)
76+ operate! (- , output. num)
77+ operate! (+ , output. num, x. num)
78+ operate_to! (output. den, copy, x. den)
79+ return output
80+ end
81+
82+ function operate_to! (output:: Rational , :: typeof (- ), y:: Integer , x:: Rational )
83+ # TODO Use `checked_mul` and `checked_sub` like in Base
84+ operate_to! (output, - , x, y)
85+ operate_to! (output, - , output)
86+ return output
87+ end
88+
4889# *
4990function promote_operation (:: typeof (* ), :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
5091 return Rational{promote_operation (* , S, T)}
5192end
93+
94+ function promote_operation (:: typeof (* ), :: Type{Rational{S}} , :: Type{I} ) where {S,I<: Integer }
95+ return promote_operation (* , Rational{S}, Rational{I})
96+ end
97+
98+ function promote_operation (:: typeof (* ), :: Type{I} , :: Type{Rational{S}} ) where {S,I<: Integer }
99+ return promote_operation (* , Rational{S}, Rational{I})
100+ end
101+
52102function operate_to! (output:: Rational , :: typeof (* ), x:: Rational , y:: Rational )
53103 xn, yd = Base. divgcd (promote (x. num, y. den)... )
54104 xd, yn = Base. divgcd (promote (x. den, y. num)... )
@@ -57,6 +107,48 @@ function operate_to!(output::Rational, ::typeof(*), x::Rational, y::Rational)
57107 return output
58108end
59109
110+ function operate_to! (output:: Rational , :: typeof (* ), x:: Rational , y:: Integer )
111+ xn = x. num
112+ xd, yn = Base. divgcd (promote (x. den, y)... )
113+ operate_to! (output. num, * , xn, yn)
114+ operate_to! (output. den, copy, x. den)
115+ return output
116+ end
117+
118+ function operate_to! (output:: Rational , :: typeof (* ), y:: Integer , x:: Rational )
119+ return operate_to! (output, * , x, y)
120+ end
121+
122+ # //
123+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Rational , y:: Rational )
124+ xn, yn = Base. divgcd (promote (x. num, y. num)... )
125+ xd, yd = Base. divgcd (promote (x. den, y. den)... )
126+ operate_to! (output. num, * , xn, yd)
127+ operate_to! (output. den, * , xd, yn)
128+ return output
129+ end
130+
131+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Rational , y:: Integer )
132+ xn, yn = Base. divgcd (promote (x. num, y)... )
133+ operate_to! (output. num, copy, xn)
134+ operate_to! (output. den, * , x. den, yn)
135+ return output
136+ end
137+
138+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Integer , y:: Rational )
139+ xn, yd = Base. divgcd (promote (x, y. den)... )
140+ operate_to! (output. num, * , xn, yd)
141+ operate_to! (output. den, copy, y. num)
142+ return output
143+ end
144+
145+ function operate_to! (output:: Rational , op:: Union{typeof(/), typeof(//)} , x:: Integer , y:: Integer )
146+ n, d = Base. divgcd (promote (x, y)... )
147+ operate_to! (output. num, copy, n)
148+ operate_to! (output. den, copy, d)
149+ return output
150+ end
151+
60152# gcd
61153function promote_operation (:: Union{typeof(gcd),typeof(lcm)} , :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
62154 return Rational{promote_operation (gcd, S, T)}
0 commit comments