Making my first steps into julia, coming from R and python. Following the getting started guide, I noticed the following:
2^62
# 4611686018427387904
2^63 # <--- This is negative?
# -9223372036854775808
2^63 > 1
# false
2^64
# 0 # this is zero, but that makes sense if it is a 64 bit float
Since julia is using machine integers (which use Twos-Complement), an integer with a leading 1 is negative.
In contrast, python automatically grows the integer type as necessary - this is much slower for general use though, which is why its not done in julia.
There is SaferIntegers.jl, if you want checked arithmetic with integers. You can also use functions in Base.Checked directly, like Base.Checked.checked_add, for example.
And we do this for the same reason: this is the behavior of our machines’ integers. It’s the fastest behavior possible. Doing anything else requires extra operations to emulate some different sort of behavior.
For the how much does this cost question, the answer is anywhere from 10% to 20x. A typical cost is usually in the 2x case, but the added complication can easily prevent massive optimizations.
I don’t think that PSA should be a link to various docs other than the manual, or target users from specific programming languages. Once you start doing that, it gets too long (it already is) and even fewer people would read it.
Sometimes I wonder if it would be a good idea to make a blog post about stuff like this. Hit some of the classics like 1.0 != 1.0 (in julia this is actually handled very well compared to say C/C++). By showing some of the boundaries of computing issues we get the opportunity to teach some computer science stuffs to people while introducing the language. Could be fun to show off the interop of Julia too, but maybe this is getting off topic.
Edit someone asked me what I mean by 1.0 != 1.0. Unfortunately Cxx isn’t working with Julia 1.4+ but you can get this kind of behaviour with big floats :). So for example:
a = BigFloat(0.1)
BigFloat(1.0) == BigFloat(10.) * a
# therefore 1.0 != 1.0
So in C/C++ you will deal with this issue a bit, its due to numerical precision. Meanwhile - Julia is great because
It is impossible to please everyone — if parts of that FAQ (one of the oldest, actually) were omitted, I imagine people would suggest that they are added. At least when they are there, the reader has the option of just skimming through sections.
IMHO the short comments in this thread from @ericphanson, @simeonschaub, @mbauman and @Oscar_Smith concisely cover most of the information that newcomers typically want when first encountering this issue. I agree with @Tamas_Papp that we shouldn’t remove information from the FAQ entry, but maybe it could be reorganized in a way that it starts off with similar concise and to-the-point descriptions, and then goes into more technical detail explaining the background and motivation for these decisions.
I think that there are three layers of answers to the original question in this post:
Why is 2^63 negative? Because Julia uses overflow/wraparound/native arithmetic.
Why does Julia do this? Because it is fast.
What if I don’t like this? That’s fine, Julia is super-extensible. Just use one of the relevant packages (list follows: …) if they implement what you want, or roll your own.
Separating the answer to subheadings along these lines would be nice. (My wording above is informal, a PR should consider rephrasing).