296
296
Base. convert (:: Type{FD{T, f}} , x:: FD{T, f} ) where {T, f} = x # Converting an FD to itself is a no-op
297
297
298
298
function Base. convert (:: Type{FD{T, f}} , x:: Integer ) where {T, f}
299
- reinterpret (FD{T, f}, T (widemul (x, coefficient (FD{T, f}))))
299
+ C = coefficient (FD{T, f})
300
+ throw_inexact () = throw (InexactError (:convert , FD{T, f}, x))
301
+ typemin (T) <= x <= typemax (T) || throw_inexact ()
302
+ xT = convert (T, x) # This won't throw, since we already checked, above.
303
+ # Perform x * C, and check for overflow. This is cheaper than a widemul, especially for
304
+ # 128-bit T, since those widen into a BigInt.
305
+ v = _mul_checked_overflow (throw_inexact, xT, C)
306
+ return reinterpret (FD{T, f}, v)
307
+ end
308
+ function Base. convert (:: Type{FD{BigInt, f}} , x:: Integer ) where {f}
309
+ # We specialize on f==0, since julia can't eliminate BigInt multiplication.
310
+ if f == 0
311
+ # If x is already a BigInt, this is a no-op, otherwise we alloc a new BigInt.
312
+ return reinterpret (FD{BigInt, f}, BigInt (x))
313
+ end
314
+ # For the normal case, we multiply by C, which produces a BigInt value.
315
+ C = coefficient (FD{BigInt, f})
316
+ # This can't throw since BigInt and BigFloat can hold any number.
317
+ v = x * C
318
+ return reinterpret (FD{BigInt, f}, v)
319
+ end
320
+
321
+ # x * y - if overflow, report an InexactError(FDT, )
322
+ function _mul_checked_overflow (overflow_callback, x, y)
323
+ v, overflow = Base. mul_with_overflow (x, y)
324
+ if overflow
325
+ overflow_callback ()
326
+ end
327
+ return v
300
328
end
301
329
302
330
Base. convert (:: Type{T} , x:: AbstractFloat ) where {T <: FD } = round (T, x)
@@ -310,7 +338,10 @@ function Base.convert(::Type{FD{T, f}}, x::FD{U, g}) where {T, f, U, g}
310
338
if f ≥ g
311
339
# Compute `10^(f - g)` without overflow
312
340
powt = div (coefficient (FD{T, f}), coefficient (FD{U, g}))
313
- reinterpret (FD{T, f}, T (widemul (x. i, powt)))
341
+ v = _mul_checked_overflow (promote (x. i, powt)... ) do
342
+ throw (InexactError (:convert , FD{T, f}, x))
343
+ end
344
+ reinterpret (FD{T, f}, T (v))
314
345
else
315
346
# Compute `10^(g - f)` without overflow
316
347
powt = div (coefficient (FD{U, g}), coefficient (FD{T, f}))
0 commit comments