@@ -20,9 +20,18 @@ function operate!(::typeof(one), x::Rational)
20
20
end
21
21
22
22
# +
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}
24
24
return Rational{promote_sum_mul (S, T)}
25
25
end
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
+
26
35
function operate_to! (output:: Rational , :: typeof (+ ), x:: Rational , y:: Rational )
27
36
xd, yd = Base. divgcd (promote (x. den, y. den)... )
28
37
# TODO Use `checked_mul` and `checked_add` like in Base
@@ -32,10 +41,26 @@ function operate_to!(output::Rational, ::typeof(+), x::Rational, y::Rational)
32
41
return output
33
42
end
34
43
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)
38
54
end
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 -
39
64
function operate_to! (output:: Rational , :: typeof (- ), x:: Rational , y:: Rational )
40
65
xd, yd = Base. divgcd (promote (x. den, y. den)... )
41
66
# TODO Use `checked_mul` and `checked_sub` like in Base
@@ -45,10 +70,35 @@ function operate_to!(output::Rational, ::typeof(-), x::Rational, y::Rational)
45
70
return output
46
71
end
47
72
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
+
48
89
# *
49
90
function promote_operation (:: typeof (* ), :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
50
91
return Rational{promote_operation (* , S, T)}
51
92
end
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
+
52
102
function operate_to! (output:: Rational , :: typeof (* ), x:: Rational , y:: Rational )
53
103
xn, yd = Base. divgcd (promote (x. num, y. den)... )
54
104
xd, yn = Base. divgcd (promote (x. den, y. num)... )
@@ -57,6 +107,48 @@ function operate_to!(output::Rational, ::typeof(*), x::Rational, y::Rational)
57
107
return output
58
108
end
59
109
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
+
60
152
# gcd
61
153
function promote_operation (:: Union{typeof(gcd),typeof(lcm)} , :: Type{Rational{S}} , :: Type{Rational{T}} ) where {S,T}
62
154
return Rational{promote_operation (gcd, S, T)}
0 commit comments