Continuing the discussion from Why are there all these strange stumbling blocks in Julia?:
I first continue, answer here by forking old discussion (by clicking corner in top left corner, for the first time, good to know of it), and then in B. the floowup about unchecked:
A.
Python is actually the odd one out, does what C did (or the compiler then used), but not what current C or C++ do.
There IS an operator in Julia for floored, except not for the default, signed numbers.
I.e. there is fld
for all numbers, but ÷ (and div
) aren’t floored, so does that matter? ÷ works for all positive numbers, and when do you actually want fld
for the negative ones? I’m not sure it matters too much to have an operator for it, could then be ///
…
In the original C++ standard, -5 / 3 could be either -1 (rounding towards zero) or -2 (the floor), but -1 was recommended. In the latest C++0B draft (which is almost certainly very close to the final standard), it is -1, so finding the floor with negative numbers is more involved.
B.
Division is the slowest operation in CPUs (without accessing memory), and for floating point we do compile to one instruction. But for integers, the assembly instruction is about as slow (maybe slower, since inherently doing more work), but on top of that Julia adds a lot of code for fld and div, calling e.g. intrinsic checked_sdiv_int. So what is the unchecked variant of it, or where/how can I get such access?
julia> @edit Base.checked_sdiv_int(5, 2)
ERROR: could not determine location of method definition
julia> a=-5; b = 2; # Here Int64, since running on 64-bit platform, and it makes it over 2x worse.
julia> @btime $a ÷ $b
15.455 ns (0 allocations: 0 bytes)
-2
julia> @btime fld($a, $b)
16.964 ns (0 allocations: 0 bytes)
-3
julia> @btime $a >> 1 # this is floored division operator too, by 2, works for by 4, 8, etc.
3.502 ns (0 allocations: 0 bytes)
-3
julia> a=Int32(-5); b=Int32(2); @btime div($a, $b)
6.579 ns (0 allocations: 0 bytes)
-2
None of those are actually optimal code. [E.g. >>
is a bit faster the floating-point /
but should be a lot faster.]
(rounding can go toward zero or toward negative infinity in pre-C99; in C99+, the rounding goes toward 0). The result has type
int
.floor(a/b)
does the same division, converts the result to double, discards the (nonexistent) fractional part, and returns the result as a double.
Trivia (not exported, but IS public):
help?> Base.checked_length
Base.checked_length(r)
Calculates length(r), but may check for overflow errors where applicable when the result doesn't fit into Union{Integer(eltype(r)),Int}.
Don’t worry I see defined:
checked_length(r) = length(r) # for most things, length doesn't error
Is the latter line actually needed?: