BUG修复:PaxScript没有无符号右移操作

本文探讨了PaxScript中位运算的问题,特别是无符号右移运算的错误实现,并给出了具体的修改方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PaxScript没有无符号右移操作??

   alert( [ -32045063 >>> 20  ] );
IE  中结果 = 4065
PAXScript 中结果 = –31

看看JavaScript里>>和>>>的定义:
>>
右移第一个运算数中的所有位,移动的位数由第二个运算数指定,移动的位数应该是0-31的整数。舍弃右边移出的位,填补在左边的位由原运算数的符号位决定,以便保持结果的符号和原运算数一致。如果第一个运算数是正的,就用0填补结果的高位,如果第一个运算数是负的,就用1填补结果的高位。将一个值右移1位,相当于用2除它(丢弃余数),右移2位,相当于用4除它,以此类推。例如7>>1=3, -7>>1 = –4


>>>
表示用0不足的右移运算符。>>>和>>一样,只是从左边移入的总是0,与原运算数的符号无关
例如 -1>>4=-1,但-1>>>4 = 268435455(0x0fffffff).


经测试发现: delphi 里shr 相当于 JavaScript 的 >>> ,但是JavaScript 的 >> 在delphi没有对应的函数。

paxScript的bug:作者把>> 和 >>> 的作用搞反了!!!
原来的代码:(BASE_SYS.pas)
//作者写此函数作用是实现 JavaScript的>>>。但实际他的作用是JavaScript里的>>。
function _Shr(X, Y: Integer): Variant;
var
  I, J: Integer;
begin
  J := X shr Y;   //但此处已经达到了>>>目的!
  if X >= 0 then
  begin
    result := J;
    Exit;
  end;
  if Y < 0 then
  begin
    result := NaN;
    Exit;
  end;
  for I:=31 downto 32 - Y do  //设置高位 实际效果成了>>
    SetBit(J, I);
  result := J;
end;

procedure SetBit(var Value: Integer; const Bit: Integer);
begin
  Value := Value or (1 shl Bit);
end;

修改方法:
//base_code.pas
procedure TPAXCode.OperUnsignedRightShift_Ex;
var
  V1, V2: Variant;
begin
  with SymbolTable, Prog[N] do
  begin
    V1 := VariantValue[Arg1];
    V2 := VariantValue[Arg2];
    if IsObject(V1) and IsObject(V2) then
    begin
      FindBinaryOperator('op_UnsignedRightShift', V1, V2);
      if AltArg1 > 0 then
      begin
        OperBinaryOperator;
        Exit;
      end
      else
      begin
        //VariantValue[Res] := _shr(ToNumber(V1), ToNumber(V2));
        //ked mod 2009年10月23日 shr = >>>
        V1 := ToNumber(V1);
        if V1 = NaN then  //NaN当成0处理。
          VariantValue[Res] := 0
        else
          VariantValue[Res] := V1 shr  ToNumber(V2)
        end;
        //end ked mod 2009年10月23日 
      end;
    end
    else
    begin
      //VariantValue[Res] := _shr(ToNumber(V1), ToNumber(V2));
      //ked mod 2009年10月23日 shr = >>>
      V1 := ToNumber(V1);
      if V1 = NaN then  //NaN当成0处理。
        VariantValue[Res] := 0
      else
        VariantValue[Res] := V1 shr  ToNumber(V2) ; 
      //end ked mod 2009年10月23日
  end;
  InvokeOnChangedVariable;
  SetFOP(OP_UNSIGNED_RIGHT_SHIFT);
  Inc(N);
end;

procedure TPAXCode.OperRightShift_Ex;
//ked add
var
  V1, V2: Variant;
//end ked add
begin
  with SymbolTable, Prog[N] do
  begin
    if AltArg1 > 0 then
    begin
      OperBinaryOperator;
      Exit;
    end;

    //ked add
    V1 := VariantValue[Arg1];
    V2 := VariantValue[Arg2];
    //end ked add

      //VariantValue[Res] := ToInt32(ToInt32(VariantValue[Arg1])) shr ToNumber(VariantValue[Arg2]);
      //ked mod 2009年10月23日 _shr = >>
      V1 := ToNumber(V1);
      if V1 = NaN then  //NaN当成0处理。
        VariantValue[Res] := 0
      else
        VariantValue[Res] := _Shr(V1 , ToNumber(V2)) ;
      //end ked mod 2009年10月23日
  end;
  InvokeOnChangedVariable;
  SetFOP(OP_RIGHT_SHIFT);
  Inc(N);
end;


ok, bug修复完毕,初步测试ok。 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值