加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi XE中的奇怪SHL操作

发布时间:2020-12-15 04:23:35 所属栏目:大数据 来源:网络整理
导读:v:= v shl b有什么问题?我正在尝试计算mask = 2n-1 like 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 s
v:= v shl b有什么问题?我正在尝试计算mask = 2n-1 like 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;

……但是,我不开心.

解决方法

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.

因此,64位值上的1 shl 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;

因此,当y是常量时,似乎存在64位值的编译器错误.

注意在64位模式下,1 shl 64导致1.

所以这个bug只存在于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中得到解决.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读