I think Perl does both: taking $i%32 as its RHS, and drop the higher bits, just keeping the lower 32 bits, from the result.
No, perl is doing exactly as it says in the docs; it is just using the underlying C << operator, whose result is undefined for overflows. That means the result will vary based on C compiler and/or CPU architecture.
from pp.c:
const IV shift = POPi;
if (PL_op->op_private & HINT_INTEGER) {
const IV i = TOPi;
SETi(i << shift);
}
else {
const UV u = TOPu;
SETu(u << shift);
}
Dave. | [reply] [d/l] |
<q>You don't explain it.</q>
He explained it very exactly, _if_ you are familiar with the terminology
of computer science. In computer science, when we say that the result of
a particular operation is "undefined", we don't mean that you get the
Perl value undef. (That would be the undefined _value_ -- this is the
undefined _behavior_.) This terminology is older than Perl and means
that in fact, depending on your compiler, your hardware
architecture, your OS, your C libraries, and the phase of the moon,
the result can and might very well be any of the following:
- 0
- 1
- -1
- 3
- 9827345908794823.74598723459879
- Your program crashes immediately.
- Everything seems fine at first, but your program crashes
a few minutes later for no apparent reason.
- The entire operating system crashes. This result is
unlikely under modern operating systems, unless the code
with the undefined behavior is in kernel space or an
important hardware driver (e.g., the video driver or
a mass storage driver). Since Perl is seldom used
for kernels or hardware drivers, this result is unlikely
to be triggered by Perl code on modern systems.
- Other variables elsewhere in your program have their
values changed without warning. (This particular result
is unlikely in Perl, but the C library and compiler
retain the right to do this if you do something the
result of which is undefined behavior.)
- Small dragons fly out of your nose and attempt to re-enter
your body elsewhere.
<q>If you take the lower 32 bits of the result that's too big to fit into an integer, I expect</q>
When it comes to undefined behavior, you don't get to have expectations.
Frankly I would prefer that Perl intercept such things and define their
behavior, even if the definition is a fatal error that stops your
program and prints a suitable error message. But it doesn't.
The long and short of it is that when the behavior is undefined
that means the burden is on you, the programmer, to carefully avoid
doing such things. If the result of doing left shift more than 32
times is undefined, then you must not do left shift more than 32 times --
or you must use a math library that defines it, such as the one mentioned
in another reply.
Sanity? Oh, yeah, I've got all kinds of sanity. In fact, I've developed whole new kinds of sanity. Why, I've got so much sanity it's driving me crazy.
| [reply] |