Strange SHL operation in Delphi XE

What happened to v:=v shl b? I am trying to calculate mask = 2 n -1 as mask:=1 shl n-1, but does not work for the integer variable n = 64.

program UInt64Test;

{$APPTYPE CONSOLE}

var
  u,v,w:uint64;
const
  a=64;
var
  b:integer=a;
  c:integer=a-1;

begin
  u:=1; v:=1; w:=1;
  u:=u shl a;
  v:=v shl b;
  w:=w shl 1 shl c;
  writeln(u);
  writeln(v);
  writeln(w);
  readln;
end.

Conclusion:

0
1
0

I suspected it was valso zero.

Decided how 2 shl (n-1)-1. In this case, the compiler will execute the machine shl(not __llshl):

function reciprocal(o:uint64;n:byte=64):uint64; // result * o = 1 (mod 2ⁿ)
var
  b,m,t:uint64;
begin
  result:=0;
  t:=2 shl (n-1)-1;
  m:=0; b:=1;
  while b<>0 do begin
    m:=m or b;
    if ((o*result) and m)<>1 then result:=result or b;
    b:=(b shl 1) and t;
  end;
end;

... but, I'm not happy.

+5
source share
1 answer

From documentation:

x shl y x shr y x y , ( x ) x 2 ^ y; , x. , N 01101 ( 13), N shl 1 11010 ( 26). , y x. , , x , x shl 40 x shl 8, 32 , 40 mod 32 - 8.

, 1 shl 64 64- 1 shl 0, 1.

const
  aa = 32;
var
  x,y,z : Cardinal;
...
x := 1;
y := 32;
z := x shl aa; // Gives z = 1
z := x shl 32; // Gives z = 1
z := x shl y;  // Gives z = 1;

, , 64- , y .

64 , 1 shl 64 1.

, 32- .

QC112261 SHL operations by constant fails.


0 y >= 64, :

function ShiftLeft( AValue : UInt64; bits : Integer) : UInt64; inline;
begin
  if (bits > 63) then 
    Result := 0 // Avoid bits being modified modulo 64
  else
    Result := AValue shl bits;
end; 

XE4.

+10

All Articles