首頁 >web前端 >js教程 >使用 Big.js 進行精確分配:處理舍入和剩餘重新分配

使用 Big.js 進行精確分配:處理舍入和剩餘重新分配

Barbara Streisand
Barbara Streisand原創
2024-12-31 17:39:081025瀏覽

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

在處理大量的分數分配時,捨入誤差和剩餘重新分配成為重大挑戰。這些問題不僅限於財務計算;它們可以發生在其他領域,例如資源分配、任務調度或預算分配。在本文中,我們示範了一種使用 JavaScript 中的 big.js 函式庫進行驗證和測試的方法,以實現精確分配,同時有效處理舍入和剩餘重新分配。


問題:在股票之間分配資金

想像一個場景,您需要根據多隻股票各自的百分比分配大量資金。例如:

  • 股票A:50.5%
  • 股票B:30.3%
  • 股票C:19.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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn