Skip to content

Commit 316e759

Browse files
committed
Refactor overflow issues with division
1 parent 81ed5dd commit 316e759

File tree

2 files changed

+15
-27
lines changed

2 files changed

+15
-27
lines changed

src/FixedPointDecimals.jl

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,31 +142,21 @@ end
142142

143143
function /{T, f}(x::FD{T, f}, y::FD{T, f})
144144
powt = T(10)^f
145-
quotient, remainder = fldmod(widemul(x.i, powt), widen(y.i))
146-
reinterpret(FD{T, f}, T(_round_to_even(quotient, remainder, widen(y.i))))
145+
quotient, remainder = fldmod(widemul(x.i, powt), y.i)
146+
reinterpret(FD{T, f}, T(_round_to_even(quotient, remainder, y.i)))
147147
end
148148

149149
# these functions are needed to avoid InexactError when converting from the integer type
150150
function /{T, f}(x::Integer, y::FD{T, f})
151-
S = promote_type(typeof(x), T)
152-
xi, yi = promote(x, y.i)
153-
154-
# The integer part of our result is x.i * 10^2f / y.i, so we need to
155-
# double-widen to get a precise result.
156-
powt = S(10)^f
151+
powt = T(10)^f
157152
powtsq = widemul(powt, powt)
158-
quotient, remainder = fldmod(widemul(widen(xi), powtsq), widen(widen(yi)))
159-
160-
reinterpret(FD{T, f},
161-
T(_round_to_even(quotient, remainder, widen(widen(yi)))))
153+
quotient, remainder = fldmod(widemul(x, powtsq), y.i)
154+
reinterpret(FD{T, f}, T(_round_to_even(quotient, remainder, y.i)))
162155
end
163156

164157
function /{T, f}(x::FD{T, f}, y::Integer)
165-
S = promote_type(T, typeof(y))
166-
xi, yi = promote(x.i, y)
167-
168-
quotient, remainder = fldmod(xi, yi)
169-
reinterpret(FD{T, f}, T(_round_to_even(quotient, remainder, yi)))
158+
quotient, remainder = fldmod(x.i, y)
159+
reinterpret(FD{T, f}, T(_round_to_even(quotient, remainder, y)))
170160
end
171161

172162
# integerification

test/runtests.jl

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ end
199199
@testset for x in keyvalues[FD2]
200200
@test x / one(x) == x
201201

202-
# signed integers using two's complement have one additional negative value
202+
# signed integers using two's complement have one additional negative value
203203
if x < 0 && x == typemin(x)
204204
@test_throws InexactError x / -one(x)
205205
else
@@ -268,18 +268,16 @@ end
268268
@test 129 / FD2(200) == FD2(0.64)
269269
@test -129 / FD2(200) == FD2(-0.64)
270270

271-
# Use of Float or BigFloat internally should not change the calculated
272-
# result
271+
# Use of Float or BigFloat internally should not change the calculated result
273272
@test round(Int, 109 / 200 * 100) == 55
274273
@test round(Int, BigInt(109) / 200 * 100) == 54 # Correct
275274

276-
x = FD{Int128,2}(1.09)
277-
@test x / Int128(2) == x / BigInt(2) == FD2(0.54)
278-
@test x / FD{Int128,2}(2) == x / Int128(2) == FD2(0.54)
279-
280-
y = FD{Int128,2}(200)
281-
@test Int128(109) / y == BigInt(109) / y == FD2(0.54)
282-
@test FD{Int128,2}(109) / y == Int128(109) / y == FD2(0.54)
275+
x = FD2(1.09)
276+
y = FD2(200)
277+
for T in [FD2, Int8, Int128, BigInt]
278+
@test x / T(2) == FD2(0.54)
279+
@test T(109) / y == FD2(0.54)
280+
end
283281
end
284282

285283
@testset "without promotion" begin

0 commit comments

Comments
 (0)