ホームページ  >  記事  >  ウェブフロントエンド  >  js の桁数が多すぎてパラメータの精度が失われる例を共有します。

js の桁数が多すぎてパラメータの精度が失われる例を共有します。

零下一度
零下一度オリジナル
2017-04-27 14:49:193279ブラウズ

js の桁数が大きすぎてパラメーターの精度が失われる例を共有します

最近、js 関数でパラメーターを渡すときに、渡される桁数が比較的大きいという奇妙な問題に遭遇しました。引数を出力すると、渡されたパラメータが変更されていることがわかります。

そこで調べてみたところ、確かにjsの精度の低下が原因であることが分かりました。私の解決策は、精度を失わないように、数値型を文字型の送信に変更することです。以下に示すように:

JS 数値が精度を失う理由

コンピューターのバイナリ実装と桁数の制限 数値の中には有限に表現できないものがあります。 pi 3.1415926...、1.3333... など、一部の無理数を有限に表現できないのと同じです。 JSはIEEEに準拠しています 754 仕様では、64 ビットを占有する倍精度ストレージ (倍精度) を使用します。図に示すように

意味

  • 符号ビットを表すために 1 ビットが使用されます

  • 指数を表すために 11 ビットが使用されます

  • 52 ビットが仮数を表します

フローティングこのとき

0.1 >> 0.0001 1001 1001 1001…(1001无限循环)
0.2 >> 0.0011 0011 0011 0011…(0011无限循环)

などのポイント数 四捨五入は10進法しか真似できませんが、2進法は0と1しかないので四捨五入すると0と1になります。これが、コンピュータの一部の浮動小数点数演算におけるエラーや精度の低下の根本原因です。

大きな整数の精度の低下は、浮動小数点数の精度の低下と本質的に同じです。仮数部の最大桁数は 52 桁であるため、JS で正確に表現できる最大の整数は Math.pow(2, 53) です。 10 進数では 9007199254740992 です。

9007199254740992より大きい場合は精度が落ちる可能性があります

9007199254740992     >> 10000000000000...000 // 共计 53 个 0
9007199254740992 + 1 >> 10000000000000...001 // 中间 52 个 0
9007199254740992 + 2 >> 10000000000000...010 // 中间 51 个 0

実際

9007199254740992 + 1 // 丢失
9007199254740992 + 2 // 未丢失
9007199254740992 + 3 // 丢失
9007199254740992 + 4 // 未丢失

結果は図の通りです

上記により、一見有限に見える数がバイナリでは無限であることが分かりますストレージビットのため、数値の制限に「丸め」が発生し、精度の低下が発生します。

想了解更深入的分析可以看这篇论文(又长又臭):What Every Computer Scientist Should Know About Floating-Point Arithmetic

三、解决方案

对于整数,前端出现问题的几率可能比较低,毕竟很少有业务需要需要用到超大整数,只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度。

对于小数,前端出现问题的几率还是很多的,尤其在一些电商网站涉及到金额等数据。解决方式:把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数

// 0.1 + 0.2
(0.1*10 + 0.2*10) / 10 == 0.3 // true

以上がjs の桁数が多すぎてパラメータの精度が失われる例を共有します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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