v:=v shl b
有什么问题?我试图计算mask=2n-1,像mask:=1 shl n-1
一样,但对于整数变量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.
输出:
0
1
0
我也怀疑 v
是零。
解决方法为 2 shl (n-1)-1
。在这种情况下,编译器执行机器的 shl
(而不是 __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;
...但是,我不开心。
v := v shl UInt64(b);
。 - valex__llshl
函数后,发现b被掩码为$3F。这意味着移位操作是用零完成的。结果将为1。 - LU RD__llshl
对于n=64执行移位操作->结果为0,这与机器指令不同。现在通过掩码$3F进行了修复,但Delphi优化器中仍然执行移位操作,例如u := u shl a
并且仍然分配0。 - pf1957