What's wrong with v:=v shl b
? I'm trying to calculate mask = 2n-1 like mask:=1 shl n-1
, but fails for 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.
Output:
0
1
0
I suspected v
to be zero too.
Solved like 2 shl (n-1)-1
. In this case compiler perform 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.
From the documentation
:
The operations x shl y and x shr y shift the value of x to the left or right by y bits, which (if x is an unsigned integer) is equivalent to multiplying or dividing x by 2^y; the result is of the same type as x. For example, if N stores the value 01101 (decimal 13), then N shl 1 returns 11010 (decimal 26). Note that the value of y is interpreted modulo the size of the type of x. Thus for example, if x is an integer, x shl 40 is interpreted as x shl 8 because an integer is 32 bits and 40 mod 32 is 8.
So 1 shl 64 on a 64 bit value is interpreted as 1 shl 0 which is 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;
So it seems that there is a compiler bug for 64 bit values when y is a constant.
Note in 64 bit mode, 1 shl 64 results in 1.
So the bug is only in the 32 bit compiler.
Reported as QC112261 SHL operations by constant fails
.
If the wanted result of your shift operation was 0 for a y value >= 64, then this function can be used:
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;
Update
This compiler bug is resolved in version XE4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With