One idea would be to enable checked arithmetic during unit testing, or have some global flag in your project indicating whether you’re running in production mode or not, and use checked arithmetic if not.
I’m sure (and I really hope) there are better ways of doing this, but here’s a simple proof-of-concept:
function enable_checked_exp()
@eval Base begin
function ^(a::T, b::T) where {T<:BitInteger}
r1 = invoke(^, Tuple{Integer, Integer}, a, b)
r2 = BigInt(a) ^ BigInt(b)
r1 == r2 ? r1 : throw(OverflowError("$a^$b: got $r1, expected $r2"))
end
end
end
function gracefully_disable_checked_exp()
atexit(() -> run(`julia -q`))
exit()
end
Demonstration:
julia> 6.023 * 10^23
1.2068671807961137e18
julia> enable_checked_exp();
julia> 6.023 * 10^23
ERROR: OverflowError: 10^23: got 200376420520689664, expected 100000000000000000000000
julia> 10^17
100000000000000000
julia> gracefully_disable_checked_exp()
julia> 6.023 * 10^23
1.2068671807961137e18