这里有几个不同的规范部分在起作用。让我们从错误中倒退。
错误状态:arguments to a comparison must both be signed, unsigned or doubles; int and int are given
。因此,问题在于以下代码行:
...
if(a < b) { // <- Here
log(0.0);
} else {
log(1.0);
}
...
如果我们查找operator 的类型语义<
,我们会得到下表:
(signed, signed) → int ∧
(unsigned, unsigned) → int ∧
(double, double) → int
这清楚地反映了错误消息的措辞;该<
运算符仅对有符号、无符号或双精度类型之间的比较有效。“但是为什么?”,你问?
类型的描述int
可能会给我们一个提示。这是一段摘录:
int 类型是符号未知的 32 位整数类型。在 asm.js 中,变量的类型从来没有已知的符号。[...] 但是,这种表示会在有符号和无符号数字之间产生重叠,从而导致在确定它们代表的 JavaScript 数字时产生歧义。例如,位模式 0xffffffff 可以表示 4294967295 或 -1,具体取决于符号。因此,不允许 int 类型的值转义到外部(非 asm.js)JavaScript 代码中。
因此,单独进行比较操作,ASM.js 将无法知道两个int
值中的哪一个小于另一个,因为它不知道整数的符号。
那么,为什么变量被解析为 type int
?
由于您要在函数本身内部声明变量,因此我们必须参考规范的以下部分:
变量声明的类型由它们的初始化器决定。变量初始值设定项可以是浮点文字,它是任何带有字符的数字文字。在他们的源代码中,并且类型为double。或者,初始值设定项可以是[-231, 232) 范围内的整数文字,其类型为int。
我们去吧。由于您将变量初始化为var a=0, b=0;
, 这对应于规范的后半部分,因此解析为int
.
那么我们如何解决这个问题呢?好吧,我们需要一个类型转换为<
运算符支持的东西。运算符可以采用|
两个intish
表达式,并返回 a signed
,这样就足够了。
if ((a|0) < (b|0)) {
log(0.0);
} else {
...
注意: 类型图以及运算符类型规则在尝试调试此类类型问题时非常有用。