Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-08

shift right operation with variables

6 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang

Hi All,

I noticed a strange behavior with the following program:

program tt;
{$mode objfpc}{$H+}
uses sysutils;
var
  res: Integer;
  mask1, mask2: QWord;
begin
  mask1 := $FFFFFFFFFFFFFFFF shr 24;
  WriteLn(IntToHex(mask1, 16));
  res := 24;
  mask2 := $FFFFFFFFFFFFFFFF shr res;
  WriteLn(IntToHex(mask2, 16));
end.

The output is:

000000FFFFFFFFFF
00000000000000FF

Why they are different? How can I ensure the result is like SHR with constant.

Thanks!

Reply by email

waldo kitty
to Xiangrong Fang
Xiangrong Fang wrote 6 lines
The output is: 000000FFFFFFFFFF 00000000000000FF Why they are different? How can I ensure the result is like SHR with constant.

being curious, i tried your program with the same results... then i changed the var name from "res" to "foo" with the same results... i thought maybe there was some type conversion going on so i changed "foo" from "integer" to "QWord" and still got the same results... there appears to be a problem at play...

Free Pascal Compiler version 3.1.1 [2015/06/13] for x86_64

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list* unless private contact is specifically requested and granted.

Reply by email

Marco van de Voort
to Xiangrong Fang: I noticed a strange behavior with the following program: program tt; {$mode objfpc}{$H+}…

In our previous episode, Xiangrong Fang said:

Show quoted text 13 lines
var res: Integer; mask1, mask2: QWord; begin mask1 := $FFFFFFFFFFFFFFFF shr 24; WriteLn(IntToHex(mask1, 16)); res := 24; mask2 := $FFFFFFFFFFFFFFFF shr res; WriteLn(IntToHex(mask2, 16)); end. Why they are different? How can I ensure the result is like SHR with constant.

The first are two literals and is calculated at compiletime using the rules for literals.

In the second is calculated at runtime one is typed an integer, probably the large constant is downcast to integer.

To avoid that cast it to qword()

   mask2 := qword($FFFFFFFFFFFFFFFF) shr res;

Reply by email

Marco van de Voort
to Peter

In our previous episode, Peter said:

Show quoted text 7 lines
I was going to comment that the 'bitmask example doesn't work, which it didn?t, but looks like its been recently fixed by adding the needed QWord cast on the '1's. http://wiki.freepascal.org/Bit_manipulation Qwords are certainly trickier to use the Dwords.

Actually dwords had the same problems before the introduction of int64.

Now Qword is the one type without a signed type larger than it.

Reply by email

Michael Schnell
to Xiangrong Fang: I noticed a strange behavior with the following program: program tt; {$mode objfpc}{$H+}…

AFAIK literals are integer unless denoted otherwise

The type of the operands determines the operation. this is rather obvious for e.g. "+" but not obvious for shift operations.

AFAIK, the type left of the ":=" does not determine the operation. This
is not obvious for everybody.

I never rely on the hidden rules behind this mechanism (which even might be different in Pascal and C. but prefer using intermediate variables for sake of clearness.

You can be sure that GCC optimizes those away. I hope fpc does the same.

-Michael

Reply by email