[Tutor] operators >> and &

Alan Gauld alan.gauld at btinternet.com
Mon Feb 15 02:02:59 CET 2010


"Steven D'Aprano" <steve at pearwood.info> wrote

> Pardon me, but that's incorrect. Python is not assembly, or C, and the
> behaviour of bit shifting in Python is NOT machine specific.
>
> http://docs.python.org/library/stdtypes.html#bit-string-operations-on-integer-types
>
> In Python, a left shift of n MUST return the equivalent of
> multiplication by 2**n, and a right shift MUST return the equivalent of
> integer division by 2**n. Any other result is a SERIOUS bug in Python

So it seems, I apologise, I had assumed that for bit shifting
Python did indeed just pass it down to the C compiler which
in turn passes it to the CPU.

As someone who works a lot at the CPU level that's slightly
dissappointing since it makes bit shifting predictable but unreliable
from my perspective - I can't guarantee the effect on the CPU...
But since it's never actually caused me a problem I won't lose
sleep over it.

> So while I bow to your knowledge of bit operations in assembler on
> obscure four bit processors,

I haven't used 4 bit CPUs since working on the millenium
bug ~10 years ago but the same applies in higher order processors
too. I only used a 4 bit CPU since you gave a 4 bit example.
But given the above it's irrelevant, the language defines the
behaviour and I was wrong about that.


> Python does not do that. (I'm not even
> sure if Python runs on any four bit CPUs!)

Probably not but it does run  on some 8 bit ones.

>> > It is certainly good practice if you are dealing with numbers which
>> > might be more than 24 bits to start with:
>>
>> Its more than good practice there, its essential.
>
> Hardly. There are other ways of truncating a number to 8 bits

I meant the truncating was needed not the & mechanism.

> [and discussing the case where you know your input is already 8 bits]
>> In the case in point the & 255 keeps the coding style consistent
>> and provides an extra measure of protection against unexpected
>> oddities so I would keep it in there.
>
> So you add unnecessary operations to be consistent? That's terrible
> practice.

No but I don't mix two styles of guard.
If I need a guard and I'm already using masks then I'll use a mask,
I certainly wouldn't mix asserts and masks for similar functions.

If I'm sure I don't need the guard then I definitely wouldn't add one
just for consistency of style.

> So if you have an operation like this:
>
> n = 12*i**3 + 7
>
> and later on, you then want n = i+1, do you write:
>
> n = 1*i**1 + 1

No I'd write
n = i+1
rather than
n = lambda x: x+1(i)
or even (if Python had such an incr function)
n = incr(i)

since the arithmetic version is more consistent that the
function call or the lambda.

>> > cycles and needlessly complicating the code. The right way to guard
>> > against "this will never happen" scenarios is with assert:
>> >
>> > assert n.bit_length() <= 32  # or "assert 0 <= n < 2**32"
>>
>> I would accept the second condition but the mask is much faster.
>
> Premature (micro) optimizations is the root of all evil. An assert that
> can be turned off and not executed is infinitely faster than a bit
> shift which is always executed whether you want it or not.

But I did want it :-)

> And either way, the 20 seconds I lose trying to interpret the bit ops
> when I read the code is far more important than the 0.000001 seconds I
> lose executing the assert :)

Ah, but to me bit ops are normal code so I don't lose time reading
them. In fact I'd take longer to figure out the assert. Readability is all
about idioms and if you do a lot of bit tweaking masking is the normal
idiom. (The only difference is that I would have used hex rather than
decimal numbers for the masks - because I read bit patterns in hex
faster than in decimal)

>> bit_length doesn't seem to work on any of my Pythons (2.5,2.6 and
>> 3.1)
>
> It won't work in 2.5 or 2.6. You're probably trying this:
>
> 123.bit_length()

Indeed, I tried using a variable and it worked.
Thanks for that I hadn't come across bit_length() before.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/




More information about the Tutor mailing list