Checked vs unchecked, e.g. (floored) divison

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?:

The advantage of mapping ÷ to fld is that then % needs to be mod, which is not so uncommon to use with a negative first argument. Both rem and mod give you a useful cyclic behavior for positive numbers. If you go past zero mod keeps being cyclic, whereas rem makes a sign shift and goes over to a cycle with negative numbers. I’m sure there’s some context where rem is useful with negative first argument, but I’m yet to find it. In my experience mod is always the operator you want and if you carelessly use % it’s an invitation for bugs.

I’m not generally enthusiastic about Python but this is something they got right, and Julia (and many other languages) sadly didn’t.