ホームページ > ウェブフロントエンド > jsチュートリアル > Big.js による正確な割り当て: 丸めと残りの再配布の処理

Big.js による正確な割り当て: 丸めと残りの再配布の処理

Barbara Streisand
リリース: 2024-12-31 17:39:08
オリジナル
1035 人が閲覧しました

Precise Allocations with Big.js: Handling Rounding and Leftover Redistribution

大量の小数割り当てを扱う場合、丸め誤差と残りの再配分が大きな課題になります。これらの問題は財務計算に限定されません。これらは、リソースの配分、タスクのスケジュール設定、予算割り当てなどの他の領域でも発生する可能性があります。この記事では、JavaScript で big.js ライブラリを使用して、丸めと残りの再配分を効果的に処理しながら正確な割り当てを実現する、検証およびテストされた方法を示します。


問題: 株式間での資金の割り当て

複数の株式にそれぞれの割合に基づいて非常に多額の資金を割り当てる必要があるシナリオを想像してください。例:

  • 株式 A: 50.5%
  • 株式 B: 30.3%
  • 株 C: 19.2%

要件は次のとおりです:

  • 浮動小数点エラーを避けるために計算をセント単位で実行します。
  • 最初の四捨五入後に残ったセントを公平に分配します。
  • 最終的な割り当てを小数点以下 2 桁のドルに変換します。

解決策

big.js ライブラリを使用すると、任意精度の演算でこれらの課題に対処できます。完全な解決策は次のとおりです:

1.入力を初期化し、パーセンテージを比率に変換します

const Big = require("big.js");

function allocateMoney(amount, allocations) {
  // Step 1: Convert percentages to rational numbers
  let totalPercent = new Big(0);
  for (let key in allocations) {
    totalPercent = totalPercent.plus(new Big(allocations[key]));
  }

  const allocationRatios = {};
  for (let key in allocations) {
    allocationRatios[key] = new Big(allocations[key]).div(totalPercent);
  }
ログイン後にコピー

2.初期割り当てをセント単位で計算

合計金額をセントに変換し、最初の四捨五入を実行します:

  const totalCents = new Big(amount).times(100).toFixed(0); // Convert amount to cents
  const allocatedCents = {};
  for (let key in allocationRatios) {
    allocatedCents[key] = allocationRatios[key].times(totalCents).toFixed(0, 0); // Convert to int (round down)
  }
ログイン後にコピー

3.残りのセントを再分配

残りのセントを計算し、小数点以下の剰余に基づいて公平に分配します。

  let distributedTotal = new Big(0);
  for (let key in allocatedCents) {
    distributedTotal = distributedTotal.plus(new Big(allocatedCents[key]));
  }

  const remainingCents = new Big(totalCents).minus(distributedTotal).toFixed(0);

  // Sort allocations by fractional remainder descending for redistribution
  const fractionalRemainders = {};
  for (let key in allocationRatios) {
    const allocated = allocationRatios[key].times(totalCents);
    const fractionalPart = allocated.minus(allocated.toFixed(0));
    fractionalRemainders[key] = fractionalPart;
  }

  const sortedKeys = Object.keys(fractionalRemainders).sort((a, b) => {
    if (fractionalRemainders[b].gt(fractionalRemainders[a])) {
      return 1;
    }
    if (fractionalRemainders[b].lt(fractionalRemainders[a])) {
      return -1;
    }
    return 0;
  });

  for (let i = 0; i < remainingCents; i++) {
    const key = sortedKeys[i % sortedKeys.length];
    allocatedCents[key] = new Big(allocatedCents[key]).plus(1).toFixed(0);
  }
ログイン後にコピー

4.ドルに戻す

最後に、割り当てをドルに戻します:

  const allocatedDollars = {};
  for (let key in allocatedCents) {
    allocatedDollars[key] = new Big(allocatedCents[key]).div(100).toFixed(2); // Convert cents to dollars with 2 decimals
  }

  return allocatedDollars;
}
ログイン後にコピー

使用例

allocateMoney 関数を使用して株式間で資金を割り当てる方法は次のとおりです。

const totalAmount = "1234567890123456.78"; // A very large total amount
const stockAllocations = {
  "Stock A": "50.5", // 50.5%
  "Stock B": "30.3", // 30.3%
  "Stock C": "19.2", // 19.2%
};

const result = allocateMoney(totalAmount, stockAllocations);
console.log("Allocation:");
console.log(result);

// Calculate total allocated
let totalAllocated = new Big(0);
for (let key in result) {
  totalAllocated = totalAllocated.plus(new Big(result[key]));
}

console.log(`Total Allocated: $${totalAllocated.toFixed(2)}`);
ログイン後にコピー

例の出力

指定された入力の出力は次のようになります:

Allocation:
{
  'Stock A': '623456784512345.67',
  'Stock B': '374074070707407.41',
  'Stock C': '237037034903703.70'
}
Total Allocated: 34567890123456.78
ログイン後にコピー

重要なポイント

  1. big.js を使用した正確な演算:
    big.js ライブラリは、浮動小数点エラーを回避することで精度を保証します。

  2. 残り物を公平に扱う:
    小数剰余を使用して、残りのユニットを決定論的かつ公平に分配します。

  3. 合計の調整:
    すべての調整が完了したら、割り当ての合計が元の金額と一致することを確認してください。

  4. 大きな値に対してスケーラブル:
    このアプローチは非常に大量の場合にシームレスに機能するため、財務およびリソース割り当ての問題に適しています。

この方法に従うことで、高い数値精度が必要なあらゆるシナリオで正確かつ公平な割り当てを実現できます。

以上がBig.js による正確な割り当て: 丸めと残りの再配布の処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート