ここでは、仕様のいくつかの異なる部分が使用されています。エラーからさかのぼってみましょう。
エラーの状態: 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
これは、エラー メッセージの文言を明確に反映しています。演算子は、<
signed、unsigned、または double 型の間の比較に対してのみ有効です。「でも、なぜ?」とあなたは尋ねますか?
型の説明がint
ヒントになるかもしれません。ここに抜粋があります:
int 型は、符号の有無が不明な32 ビット整数の型です。asm.js では、変数の型に既知の符号がありません。[...] ただし、この表現では、符号付きの数値と符号なしの数値の間に重複が生じ、それらが表す JavaScript の数値を決定する際にあいまいさが生じます。たとえば、ビット パターン 0xffffffff は、符号に応じて 4294967295 または -1 を表すことができます。このため、int 型の値を外部 (asm.js 以外) の JavaScript コードにエスケープすることはできません。
したがって、比較演算を単独で行うと、ASM.js はint
整数の符号を認識できないため、2 つの値のどちらが小さいかを知る方法がありません。
では、変数が type として解決されるのはなぜint
ですか?
関数自体の内部で変数を宣言しているため、仕様の次の部分を参照する必要があります。
変数宣言の型は、初期化子によって決定されます。変数初期化子は浮動小数点リテラルである場合があり、これは文字 . ソースにあり、double型を持っています。または、初期化子は[-231, 232) の範囲の整数リテラルで、型はintです。
では行きましょう。変数を として初期化しているのでvar a=0, b=0;
、これは仕様の後半部分に対応し、 の型に解決されint
ます。
では、これを修正するにはどうすればよいでしょうか。さて、<
オペレーターがサポートするものへの型キャストが必要です。|
演算子は 2 つの式を取り、intish
を返すsigned
ことができるので、それで十分です。
if ((a|0) < (b|0)) {
log(0.0);
} else {
...
注: このようなタイプの問題をデバッグしようとする場合、タイプ ダイアグラムと演算子のタイプ ルールが非常に役立ちます。