Skip to content

Commit 2694747

Browse files
committed
Proper definition of mod and rem
1 parent bc1a90b commit 2694747

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

src/math.jl

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ end
7676
Base.:-(l::UnionAbstractQuantity) = new_quantity(typeof(l), -ustrip(l), dimension(l))
7777

7878
# Combining different abstract types
79-
for op in (:*, :/, :+, :-, :atan, :atand, :copysign, :flipsign, :mod),
79+
for op in (:*, :/, :+, :-, :atan, :atand, :copysign, :flipsign),
8080
(t1, _, _) in ABSTRACT_QUANTITY_TYPES,
8181
(t2, _, _) in ABSTRACT_QUANTITY_TYPES
8282

@@ -193,7 +193,7 @@ for f in (
193193
return new_quantity(typeof(q), $f(ustrip(q)), dimension(q))
194194
end
195195
end
196-
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:copysign, :flipsign, :mod)
196+
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:copysign, :flipsign,)
197197
# These treat the x as the magnitude, so we take the dimensions from there,
198198
# and ignore any dimensions on y, since those will cancel out.
199199
@eval begin
@@ -209,6 +209,41 @@ for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:copysign, :flipsign,
209209
end
210210
end
211211
end
212+
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:rem, :mod)
213+
# Need to define all rounding modes to avoid ambiguities
214+
rounding_modes = if f == :rem
215+
(RoundingMode, typeof.((RoundToZero, RoundDown, RoundUp, RoundFromZero))...)
216+
else
217+
(nothing,)
218+
end
219+
for rounding_mode in rounding_modes
220+
param, extra_f_args = if rounding_mode == RoundingMode
221+
# Add default:
222+
((), (:RoundToZero,))
223+
elseif f == :rem
224+
((:(::$rounding_mode),), (:($rounding_mode()),))
225+
else # :mod
226+
((), ())
227+
end
228+
for (type2, _, _) in ABSTRACT_QUANTITY_TYPES
229+
@eval function Base.$f(x::$type, y::$type2, $(param...))
230+
x, y = promote_except_value(x, y)
231+
dimension(x) == dimension(y) || throw(DimensionError(x, y))
232+
return new_quantity(typeof(x), $f(ustrip(x), ustrip(y), $(extra_f_args...)), dimension(x))
233+
end
234+
end
235+
@eval begin
236+
function Base.$f(x::$type, y::$base_type, $(param...))
237+
iszero(dimension(x)) || throw(DimensionError(x))
238+
return new_quantity(typeof(x), $f(ustrip(x), y, $(extra_f_args...)), dimension(x))
239+
end
240+
function Base.$f(x::$base_type, y::$type, $(param...))
241+
iszero(dimension(y)) || throw(DimensionError(y))
242+
return new_quantity(typeof(y), $f(x, ustrip(y), $(extra_f_args...)), dimension(y))
243+
end
244+
end
245+
end
246+
end
212247
function Base.ldexp(x::UnionAbstractQuantity, n::Integer)
213248
return new_quantity(typeof(x), ldexp(ustrip(x), n), dimension(x))
214249
end

0 commit comments

Comments
 (0)