Multiplication issue

This is really strange that i’m getting a negative answer for this:

10^19 * 10^-18

Output: -8.446744073709551

I think it’s the third time in a week that I’m wheeling out this classic thread:

3 Likes

Crap, you beat me to it. But on second thought, I think the documentation about overflow (Integers and Floating-Point Numbers · The Julia Language) might be more informative and less scary than a whole thread discussing whether or not it is justified?

3 Likes

Thank you for your help . :slight_smile:

1 Like

What’s the performance hit of SaferIntegers.jl these days? Based on simple tests on my machine it seems negligible.

I hope one day we can make that the default, and let people use @fastmath or similar to allow silent overflows.

For this remark the link posted by @nilshg is actually very appropriate :wink: TLDR: it’s unlikely to change (EDIT: at least anytime soon)

import BenchmarkTools: @btime
import SaferIntegers: SafeInt64

n = 100_000_000

x_unsafe = fill(Int64(1), n)
x_safe = fill(SafeInt64(1), n)

@btime sum($x_unsafe)
@btime sum($x_safe)
julia> @btime sum($x_unsafe)
  12.807 ms (0 allocations: 0 bytes)
100000000

julia> @btime sum($x_safe)
  34.277 ms (0 allocations: 0 bytes)
100000000

The penalty seems like 3x perf regression.

1 Like

Not sure about this TLDR: the discussion ends on a note that Int^Int will probably become the default (while a general solution would be more difficult to implement).
But it’s true the discussion in the related PR makes that seem unlikely.

Also the FAQ says

checked arithmetic everywhere […] ends up having a substantial cost due to compilers (LLVM and GCC) not gracefully optimizing around the added overflow checks. If this improves in the future, we could consider defaulting to checked integer arithmetic in Julia, but for now, we have to live with the possibility of overflow.

1 Like

We’ve discussed this in the past (julia#21600), and it was argued that (1) Int exponentiation is rarely performance-sensitive, and (2) there may be faster ways to check for overflow (especially for the literal powers that you commonly see in code like this).

The main obstacle is that changing this would be “too breaking for 1.x”.

Ouch that’s a huge hit! I was testing with the first example on SaferIntegers.jl’s homepage and got no significant difference:

julia> hundredths( (@belapsed test(n, +, $sa, $sb, $sc, $sd)) /
                   (@belapsed test(n, +, $a, $b, $c, $d))        )
1.0