ホームページ >ウェブフロントエンド >jsチュートリアル >me_javascript スキルで JavaScript の浮動小数点精度を学びましょう

me_javascript スキルで JavaScript の浮動小数点精度を学びましょう

WBOY
WBOYオリジナル
2016-05-16 15:32:19972ブラウズ

ほとんどのプログラミング言語には複数の数値データ型がありますが、JavaScript には 1 つしかありません。 typeof 演算子を使用して数値の型を確認できます。整数であるか浮動小数点数であるかに関係なく、JavaScript は単純に数値として分類します。

typeof 17; //number
typeof 98.6; //number
typeof -21.3; //number

実際、JavaScript の数値はすべて倍精度浮動小数点数です。これらは、IEEE754 標準で指定されている 64 ビットでエンコードされた数値 (「double」) です。この事実を見て、JavaScript が整数をどのように表現するのか疑問に思われる場合は、倍精度浮動小数点数は最大 53 桁の精度の整数を完全に表現できることを思い出してください。 –9 007 199 254 740 992 (-253) から 9 007 199 254 740 992 (253) までのすべての整数は、有効な倍精度浮動小数点数です。したがって、JavaScript には明らかな整数型が存在しないにもかかわらず、整数演算は完全に可能です。
ほとんどの算術演算子は、整数、実数、またはその両方の組み合わせを使用して計算を実行できます。

0.1 * 0.9; //0.19
-99 + 100; //1
21- 12.3; //8.7
2.5 /5; //0.5
21%8; //5

ただし、ビット算術演算子は特殊です。 JavaScript はオペランドを浮動小数点数として直接操作しませんが、操作を実行する前にオペランドを暗黙的に 32 ビット整数に変換します。 (正確には、整数の 32 ビット ビッグ エンディアン 2 の補数表現に変換されます。) ビットごとの OR 式を例に挙げます。

8|1; //9

一見単純な式でも、実際には操作を完了するにはいくつかの手順が必要です。前に述べたように、JavaScript の数値 8 と 1 は両方とも倍精度浮動小数点数です。ただし、32 ビット 0 と 1 のシーケンスである 32 ビット整数として表すこともできます。整数 8 は、次のように 32 ビットのバイナリ シーケンスとして表されます。

0000000000000000000000000001000

数値型の toString メソッドを使用して自分で表示することもできます。

(8).toString(2) //"1000"

toString メソッドのパラメータは、変換基数を指定します。この例は基数 2 (つまりバイナリ) で表されます。結果の値では、左側の余分な 0 (ビット) が最終値に影響しないため省略されます。

整数 1 は、次のように 32 ビット バイナリとして表されます。

00000000000000000000000000000001 ビットごとの OR 式は 2 つのビット シーケンスを結合します。演算に含まれる 2 ビットのいずれか 1 つが 1 である限り、演算結果のビットは 1 になります。結果をビットパターンで表現すると以下のようになります:

0000000000000000000000000001001 このシーケンスは整数 9 を表します。標準ライブラリ関数 parseInt を使用して検証することもできますが、基数 2 も使用します:

parseInt("1000", 2); //9
(繰り返しになりますが、先頭の 0 ビットは演算の結果に影響を与えないため不要です。)
すべてのビット演算子は同じように機能します。オペランドを整数に変換し、整数ビット パターンを使用して演算を実行し、最後に結果を標準の JavaScript 浮動小数点数に変換します。通常、JavaScript エンジンはこれらの変換を実行するために追加の作業を行う必要があります。数値は浮動小数点数として格納されるため、整数に変換してから浮動小数点数に戻す必要があります。ただし、場合によっては、算術式や変数さえも整数でしか操作できない場合があり、最適化コンパイラーはこれらの状況を推測し、冗長な変換を避けるために数値を内部的に整数として格納することがあります。


浮動小数点数に関する最後の警告は、浮動小数点数には常に注意する必要があるということです。浮動小数点数はよく知られているように思えるかもしれませんが、不正確であることで有名です。一見単純な算術演算でも、誤った結果が生成されることがあります。

0.1 0.2 0.300000000000004 64 ビットの精度は非常に高いですが、倍精度浮動小数点数は限られた数値セットのみを表すことができ、実数セット全体を表すことはできません。浮動小数点演算は、最も近い表現可能な実数に丸められた近似結果のみを生成できます。一連の操作を実行すると、丸め誤差が蓄積され、結果の精度がますます低くなります。丸めによって、通常予期される算術の法則から予期しない逸脱が生じる可能性もあります。たとえば、実数は結合法則を満たします。これは、任意の実数 x、y、z、(x y) z = x (y z) が常に満たされることを意味します。

ただし、浮動小数点数の場合は、常にそうとは限りません。

(0.1+0.2)+0.3; //0.60000000000000001
0.1+(0.2+ 0.3); //0.6

浮動小数点数は精度とパフォーマンスのトレードオフになります。精度を重視する場合は、浮動小数点数の制限に注意してください。効率的な解決策は、整数は丸めなしで表現されるため、可能な限り整数値の算術演算を使用することです。通貨関連の計算を実行する場合、プログラマは多くの場合、計算を整数として実行できるように、計算を実行する前に値を最小通貨単位に比例変換します。たとえば、上記の計算が米ドルである場合、それをセントの整数表現に変換できます。

整数演算の場合、丸め誤差を心配する必要はありませんが、すべての計算は -253 から 253 までの整数にのみ適用されることに注意する必要があります。

ヒント

  • JavaScript の数値はすべて倍精度浮動小数点数です。
  • JavaScript の整数は倍精度浮動小数点数のサブセットにすぎず、別個のデータ型ではありません
  • ビット演算子は、数値を 32 ビットの符号付き整数として扱います。

上記は JavaScript における浮動小数点数の紹介であり、浮動小数点演算の精度トラップに常に注意する必要があります。この記事が皆さんの学習に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。