11

asmjsの基礎を学んでいるのですが、エラーが出てしまいました。何が間違っていたのかわかりません。

TypeError: asm.js type error: arguments to a comparison must both be signed, unsigned or doubles; int and int are given

コード:

window.onload = (function(stdlib, foreign) {
    "use asm";

    var log = foreign.log;

    function main() {
        var a=0, b=0;

        a=10;
        b=20;

        if(a<b) {
            log(0.0);
        } else {
            log(1.0);
        }

        return;
    }

    return {main:main};
}(window, {log:console.log})).main;
4

2 に答える 2

11

ここでは、仕様のいくつかの異なる部分が使用されています。エラーからさかのぼってみましょう。

エラーの状態: 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 {
    ...

注: このようなタイプの問題をデバッグしようとする場合、タイプ ダイアグラム演算子のタイプ ルールが非常に役立ちます。

于 2013-09-10T18:09:32.043 に答える
3

エラー メッセージで説明されているように、比較の引数は、signed、unsigned、または doubles の両方である必要があります。これは、RelationalExpression 検証演算子テーブルで必要です。

ただし、変数aと変数には、署名されているかどうかをコンパイラが認識しない型であるとしてのみ検証されるNumericLiteralsbが割り当てられます。fixnumint

したがって、明示的な式を使用して、型が署名されていないことを検証する必要があります

if ( a>>>0 < b>>>0 )

または署名

if ( a|0 < b|0 ) // any of &, ^, <<, >> or ~~ should work
于 2013-09-10T18:04:04.717 に答える