The two faces of SHR

Like Marek Mauder in his blog post from 2009, I have run into a problem because of the different implementations of the right shift operator (shr in Pascal) in different languages.

There I was happily translating some code from Java to Object Pascal when I encountered Java's >>> operator. A quick look at the Java docs tells me this is a logical right shift. No problem, just use shr. Next I found Java's >> operator. This time its an arithmetic (sign preserving) right shift. Problem - no Pascal equivalent, and since operation was on signed integers I couldn't just use shr because there's a bug waiting to happen should any of the integers go negative.

Marek (above) said that replacing

a >> 1

with

a div 2;

worked for him.

This is fine for a single bit shift, so I thought I would see if it scaled for shifts of more than one bit. I tried dividing by 2 to the power of the number of bits to shift:

function SAR(Value: LongInt; Shift: Byte): LongInt;
begin
  Shift := Shift and 31;
  if Shift = 0 then
    Exit(Value);
  Result := LongInt(LongWord(Value) shr Shift);
  if Value < 0 then
    Result := LongInt(LongWord(Result) or ($FFFFFFFF shl (32 - Shift)));
end;

I can see several ways to optimise the function but all of them make the code less readable. So I'm not going to do the optimisations unless I have to.

I should be quite trivial to create 8, 16 and 64 bit integer overloads of the routine.

Comments

Popular posts from this blog

New Unit2NS Application Released in Beta

Embarcadero Announce RAD Studio 11 Is Coming

Some Features of the Upcoming Delphi 11 (probably)