I’m curious how that would work…
Bitshifting operates on non-negative numbers, a -1
would become an integer with all bits set to 1
, and since Elixir’s integers are ‘BigInteger’ as known in .NET then its size depends on how much is allocated within it, which will always be quite a good bit larger, which we can see when we serialize it out:
iex(1)> <<131, 98, int::binary>> = :erlang.term_to_binary(-1)
<<131, 98, 255, 255, 255, 255>>
iex(2)> int
<<255, 255, 255, 255>>
C/C++/OCaml/etc and any other language I’ve used works the same way, and thus shifting by such a huge number will be… very language dependency and not well defined. ^.^;
Such as in C/C++ shifting by a negative number, say -5, is undefined, however it will actually end up performing a modulo 32 on it to become 27 due to the way it encodes the instruction in hardware in ‘many’ situations (for a 32 bit integer that is, this is because they generate a SAL opcode in assembly that just uses the bottom 5 bits in hardware).
In general though, shifting is only well defined on unsigned integers. Using unsigned integers will either be mal-defined, undefined, or some language will come up with something arbitrary. I think it’s technically an undefined operation on the BEAM so it can do anything it wants, same as in C/C++/Java/etc…
This is of course all for shifting by a signed number. Shifting a signed number itself (left side) is of course fine, though that can be different depending on if you are doing an algebraic shifting or a bitwise shifting (C/C++ change based on the type of the operand, Java has different operators, etc…).