2

各値が [0-1) になるように配列を正規化したい..つまり、最大値が 1 になることはありませんが、最小値は 0 になる可能性があります。これは、同じ範囲の数値を返すランダム関数と同じです。

これを見ていると、.99999999999999999===1 が真であることがわかりました。同上 (1-Number.MIN_VALUE) === 1 ただし、Math.ceil(Number.MIN_VALUE) は 1 です。その他: Math.floor(.999999999999) は 0 ですが、Math.floor(.99999999999999999) は 1 です。

OK、JSには丸めの問題があります。

[0,1) の範囲に収まるように一連の数値を正規化する方法はありますか?

4

3 に答える 3

0

1 つだけご理解ください: これは...

.999999999999999999

... はただの数値リテラルです。同じように

.999999999999999998
.999999999999999997
.999999999999999996
...

...パターンが見えます。

JavaScript がこれらのリテラルをどのように扱うかは、まったく別の話です。はい、この処理は Number値を格納するために使用できるビット数によって制限されます。

可能な浮動小数点リテラルの数は、定義上無限です。それらに設定された範囲がどれほど小さいかに関係ありません。たとえば、上に示したものを考えてみましょう。何人numbers very close to 1が表現できますか? そうです、それは無限です:9行に追加し続けるだけです。

しかし、各Number値のコンテナーは非常に有限で、64 ビットです。つまり、2^64 個の異なる値 ( Infinite-InfiniteおよびNaNその中) を格納できます。それだけです。

とにかく、そのようなリテラルで作業したいですか? Numbers ではなく Strings を使用してそれらを格納します。また、いくつかの BigMath JS ライブラリ (選択してください) を使用して、それらの値を処理します。再び Strings として使用します。

しかし、あなたの質問からは、配列のNumbers- Numberについて話したように、そうではないようです。JavaScript.999999999999999999にはそのような Numberがないため、そこに格納することはできません。

于 2013-05-31T22:35:41.473 に答える
0

Javascript は 0.999999999999999994 と 1 の間の任意の数値を 1 として扱うため、.000000000000000006 を減算するだけです。

もちろん、.000000000000000006 は Javascript では 0 と評価されるため、これは思ったほど簡単ではありません。

function trueFloor(x)
{
    x = x * 100;
    if(x > .0000000000000006)
        x = x - .0000000000000006;
    x = Math.floor(x/100);
    return x;
}

編集:または、少なくともできると思います。どうやら JS は .99999999999999999 を関数に渡す前に 1 にキャストするため、次のようなことを試す必要があります。

trueFloor("0.99999999999999999")

function trueFloor(str)
{
    x=str.substring(0,9) + 0;
    return Math.floor(x); //=> 0
}

なぜそのレベルの精度が必要なのかはわかりませんが、理論的にはうまくいくと思います。ここで動作するフィドルを見ることができます

として非常に正確にキャストする限り、floatおそらくstringそれが最善の策です。

于 2013-05-31T22:36:30.777 に答える