精度の問題に対する最もわかりやすい説明たとえば、1÷3=0.33333333...という数字は、3が無限に繰り返されることは誰もが知っており、数学で表現することもできますが、コンピューターはそれを保存して、次回取り出して使用できるようにする必要があります。しかし、0.333333...この数字は無限に繰り返されますが、コンピューターにそれを保存させるにはどうすればよいでしょうか。コンピュータのメモリがどれだけ大きくても、すべてを保存することはできません。数学的な相対的な値を保存することはできず、おおよその値しか保存できないため、コンピュータがそれを保存してから使用するために取り出すと、精度の問題が発生します。 JSは数値解の精度を超える1. js で安全に扱える最大の数値は Math.pow(2,53) - 1 です。数値がこれを超えると精度が失われます。次のように数値を文字列に変換することで解決できます。 // js 最大安全数: Math.pow(2, 53)-1 a = '123456444565456.889' とします b = '121231456.32' とします // a + b = '123456565796913.209' 関数 addTwo(a, b) { //1. 2つの数値の長さを比較し、短い方の数値の前に0を追加します (a.長さ > b.長さ) の場合 { arr = Array(a.length - b.length).fill(0); とします。 b = arr.join('') + b } それ以外の場合 (a.length < b.length) { arr = Array(b.length - a.length).fill(0); とします。 a = arr.join('') + a } //2. 2 つの数字を逆にします (これは、人々は左から右に加算することに慣れていますが、数字は右から左に加算されるため、逆にすると理解しやすくなるためです) a = a.split('').reverse(); b = b.split('').reverse(); //3. 2 つの配列をループして加算します。合計が 10 より大きい場合、符号 = 1 となり、現在の位置の値は (合計 % 10) になります。 let sign = 0; // 繰り上がりがあるかどうかをマークする let newVal = []; // 最終結果を格納するために使用する for (let j = 0; j < a.length; j++) { let val = a[j] / 1 + b[j] / 1 + sign; // すべてが数値であることを確認するために 1 で割ります。ここで Number() を使用することもできます。 (値> = 10)の場合{ 符号 = 1; newVal.unshift(val % 10) // ここでは push の代わりに unshift が使用されています。これにより、reverse を使用する必要がなくなります。 } それ以外 { 符号 = 0; newVal.unshift(val) } } // 最後の加算では数字 '1' を追加する必要があります 戻り値 sign && newVal.unshift(sign) && newVal.join('') || newVal.join('') } // 他の友人の簡潔な書き方を参考にしてください function addTwo(a,b) { 温度を0にする res = '' とします a = a.split('') b = b.split('') while(a.length || b.length || temp) { temp += 数値(a.pop() || 0) + 数値(b.pop() || 0) 解像度 = (温度%10) + 解像度 温度 = 温度 > 9 } res.replace(/^0+/g, '') を返します } 2. 小数部分を加算する場合は、上記のメソッドを 1 回カプセル化すると、完全な実装は次のようになります。 a = '123456444565456.889' とします b = '121231456.32'とする // a + b = '123456565796913.209' 関数 addTwo(a = '0',b = '0', isHasDecimal=false) { //1. 2つの数値の長さを比較し、短い方の数値の前に0を追加します (a.長さ > b.長さ) の場合 { arr = Array(a.length - b.length).fill(0); とします。 b = isHasDecimal && (b + arr.join('')) || arr.join('') + b } そうでなければ (a.length < b.length) { arr = Array(b.length - a.length).fill(0); とします。 a = isHasDecimal && (a + arr.join('')) || arr.join('') + a } //2. 2 つの数字を逆にします (これは、人々は左から右に加算することに慣れていますが、数字は右から左に加算されるため、逆にすると理解しやすくなるためです) a = a.split('').reverse(); b = b.split('').reverse(); //3. 2 つの配列をループして加算します。合計が 10 より大きい場合、符号 = 1 となり、現在の位置の値は (合計 % 10) になります。 let sign = 0; // 繰り上がりがあるかどうかをマークする let newVal = []; // 最終結果を格納するために使用する for (let j = 0; j < a.length; j++) { let val = a[j] / 1 + b[j] / 1 + sign; // すべてが数値であることを確認するために 1 で割ります。ここで Number() を使用することもできます。 (値> = 10)の場合{ 符号 = 1; newVal.unshift(val % 10) // ここでは push の代わりに unshift が使用されています。これにより、reverse を使用する必要がなくなります。 } それ以外 { 符号 = 0; newVal.unshift(val) } } // 最後の加算では数字 '1' を追加する必要があります 戻り値 sign && newVal.unshift(sign) && newVal.join('') || newVal.join('') } 関数 add(a,b) { num1 = String(a).split('.') とします。 num2 = String(b).split('.') とします。 intSum = addTwo(num1[0], num2[0]) とします。 res = intSumとする num1の長さ>1 || num2の長さ>1の場合{ 小数点合計 = addTwo(num1[1], num2[1], true) とします。 (decimalSum.length > (num1[1]||'0').length && DecimalSum.length > (num2[1]||'0').length) の場合 { intSum = addTwo(intSum、decimalSum[0]) です。 小数点合計 = 小数点合計.スライス(1) res = `${intSum}.${decimalSum}` } それ以外 { res = `${intSum}.${decimalSum}` } } 戻り値 } コンソール.log(add(a, b)) // 123456565796913.209 // コンソール.log(add('325', '988')) // 1313 JSデジタル精度損失の典型的な問題を見てみましょう
要約するJS の精度外数値の問題を解決する方法についての記事はこれで終わりです。JS の精度外数値に関する関連コンテンツをさらにご覧になりたい場合は、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Windows ベースの MySQL 8.0.12 のインストール
>>: DockerでVueプロジェクトをデプロイする方法を教えます
序文MySQL マスター/スレーブ レプリケーションは、アプリケーションの高パフォーマンスと高可用性...
1. HTMLタグの前に次のような文を追加するのが最適です。 <!DOCTYPE HTML P...
目次序文バックグラウンドデータの結合フロントエンドデータ表示ページ効果表示Avue.js は、既存の...
1.html <div class="ログインボディ"> <...
目次ポータルエラー境界処理エラー境界を使用しない場合はどうなりますか?注記ポータルスロットとも言えま...
目次01. レンダリングが不要な場合はuseStateを使用する02. リンクの代わりにrouter...
クラウドサーバーを使用するとデータベースに接続できる場合もありますが、Navicat Premium...
目次1. マップを初期化する2. マップポイント3. 位置決めを有効にする4. マップの変更を監視す...
次のコマンドを使用してコンテナを作成し、ローカルの /home/dock/Downloads ディレ...
最近、コンピューターの電源を入れたところ、Geek Academy が新規ユーザーに 1 か月の無料...
ページの自動スクロール効果は JavaScript で実現できますが、今日偶然、JS 制御なしでさま...
目次1. 原因2. デバイス情報3. 準備4. Apacheをインストールする5. gitを設定する...
<br /> 特定の Web サイトを閲覧して、優れた Web ページを見つけた場合、そ...
NetEase Blog で HTML を使用する場合、テンプレートに直接コードを追加できることは...
必要:近い将来、大容量ファイルのアップロード機能を実装します。フロントエンドフレームワークのアップロ...