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
Post a Comment
Comments are very welcome, but please don't comment here if:
1) You have a query about, or a bug report for, one of my programs or libraries. Most of my posts contain a link to the relevant repository where there will be an issue tracker you can use.
2) You have a query about any 3rd party programs I feature, please address them to the developer(s) - there will be a link in the post.
3) You're one of the tiny, tiny minority who are aggressive or abusive - in the bin you go and reported you will be!
Thanks