Why do I get the following error?
julia> (-1) * UInt(1)
0xffffffffffffffff
julia> @fastmath (-1) * UInt(1)
ERROR: InexactError: convert(UInt64, -1)
Tested with Julia 1.11.4.
Why do I get the following error?
julia> (-1) * UInt(1)
0xffffffffffffffff
julia> @fastmath (-1) * UInt(1)
ERROR: InexactError: convert(UInt64, -1)
Tested with Julia 1.11.4.
@fastmath
changes operations:
julia> @macroexpand @fastmath((-1) * UInt(1))
:(Base.FastMath.mul_fast(-1, UInt(1)))
which falls back to promotion and the original operation if it’s not among the floating point types flouting IEEE-754 for speed:
$op_fast(x::Number, y::Number, zs::Number...) = # op_fast === mul_fast
$op_fast(promote(x,y,zs...)...)
# fall-back implementation that applies after promotion
$op_fast(x::T,ys::T...) where {T<:Number} = $op(x,ys...) # op === *
Unfortunately, the promotion doesn’t work for *(::Int, ::Uint)
:
julia> promote((-1), UInt(1))
ERROR: InexactError: convert(UInt64, -1)
I have no idea if this is intentional or why they’d take the extra step of promotion when the original operation would take care of it (and properly), I’d argue it’s a bug. The non-numeric method preceding the above numeric methods actually wouldn’t have this problem:
# fall-back implementation for non-numeric types
$op_fast(xs...) = $op(xs...)
Practically speaking, there’s no point in using @fastmath
for anything that doesn’t involve floating point types, and involving negative signs with an unsigned number is an unusually tricky use of overflow.
True. However, one might have a function that accepts both integer and floating point types, and one adds @fastmath
to have it for the floating point case.
Anyway, thanks!
Indeed, so proper fallbacks are still the right thing to do IMO. Forgot to mention, but the promotion for *(::Int, ::UInt)
works by %
overflow prior to promotion to get around the typical InexactError
for converting negative signed integers to unsigned ones.
Here is a link to a relevant GitHub issue: JuliaLang/julia#15489. The consensus seems to be not to throw an error in such a case. I guess the @fastmath
version was forgotten.
EDIT: I’ve created an issue on GitHub: integer multiplication errors with `@fastmath` · Issue #58188 · JuliaLang/julia · GitHub