按位操作,错误结果为Dart2Js

按位操作,错误结果为Dart2Js,dart,dart2js,zigzag-encoding,Dart,Dart2js,Zigzag Encoding,我正在用Dart对32位整数进行编码。这是我正在使用的源代码: int_encodeZigZag(int实例)=>(实例>31); int_decodeZigZag(int实例)=>(实例>>1)^(-(实例&1)); 代码在DartVM中按预期工作 但是在dart2js中,如果我输入负数,则\u decodeZigZag函数返回无效结果。例如-10-10被编码为19,应该解码回-10,但它被解码为4294967286。如果我在Chrome的JavaScript控制台中运行(实例>>1)^(-

我正在用Dart对32位整数进行编码。这是我正在使用的源代码:

int_encodeZigZag(int实例)=>(实例>31);
int_decodeZigZag(int实例)=>(实例>>1)^(-(实例&1));
代码在DartVM中按预期工作

但是在dart2js中,如果我输入负数,则
\u decodeZigZag
函数返回无效结果。例如
-10
<代码>-10被编码为
19
,应该解码回
-10
,但它被解码为
4294967286
。如果我在Chrome的JavaScript控制台中运行
(实例>>1)^(-(实例&1))
,我会得到
-10
的预期结果。对我来说,这意味着Javascript应该能够使用它的数字模型正确地运行这个操作

但是Dart2Js生成了以下JavaScript,看起来与我在控制台中测试的代码不同:

return($.JSNumber_方法.$shr(实例,1)^-(实例&1))>>0;
为什么Dart2Js会将使用的右移0添加到函数中?如果没有这种转变,结果将如预期的那样

现在我想知道,这是Dart2Js编译器中的错误还是预期的结果?有没有办法强制Dart2Js输出正确的javascript代码

还是我的飞镖密码错了

PS:还测试了将XOR分解为其他操作,但Dart2Js仍在添加右移:

final a=-(实例&1);
最终b=(实例>>1);
返回(a&b)|(-a&b);
结果:

a=-(实例&1);
b=$.JSNumber_方法.$shr(实例,1);
返回(a&b |-a&b)>>>0;

看起来我找到了输出正确结果的等效代码。dart vm和dart2js的单元测试都通过了,我现在将使用它

int _decodeZigZag(int instance) => ((instance & 1) == 1 ? -(instance >> 1) - 1 : (instance >> 1));

这次Dart2Js没有添加轮班。我仍然对这种行为的原因感兴趣。

出于效率原因,dart2js将Dart编号编译为JS编号。然而,JS只提供一种数字类型:doubles。此外,JS中的位操作总是被截断为32位

在许多情况下(如密码学),处理无符号32位更容易,因此dart2js编译位操作,使其结果为无符号32位数字

无论是选择(签名还是未签名)都不是完美的。最初,dart2js编译为带符号的32位,只有在我们过于频繁地被它绊倒时才被更改。正如您的代码所演示的,这并没有消除问题,只是将问题转移到不同的(希望不那么频繁的)用例中

不符合数字语义一直是dart2js中的一个长期缺陷,但修复它需要时间,并可能会降低生成代码的速度。在短期内,Dart开发人员(编译为JS)需要了解这个限制并解决它