Heim >Web-Frontend >js-Tutorial >Präzise Zuordnungen mit Big.js: Umgang mit Rundungen und übrig gebliebener Umverteilung

Präzise Zuordnungen mit Big.js: Umgang mit Rundungen und übrig gebliebener Umverteilung

Barbara Streisand
Barbara StreisandOriginal
2024-12-31 17:39:081048Durchsuche

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

Beim Umgang mit Teilzuteilungen großer Beträge werden Rundungsfehler und übrig gebliebene Umverteilungen zu erheblichen Herausforderungen. Diese Probleme beschränken sich nicht nur auf finanzielle Berechnungen; Sie können in anderen Bereichen wie der Ressourcenverteilung, der Aufgabenplanung oder der Budgetzuweisung auftreten. In diesem Artikel demonstrieren wir eine verifizierte und getestete Methode unter Verwendung der big.js-Bibliothek in JavaScript, um präzise Zuordnungen zu erreichen und gleichzeitig Rundungen und übrig gebliebene Umverteilung effektiv zu handhaben.


Problem: Mittel auf Aktien verteilen

Stellen Sie sich ein Szenario vor, in dem Sie einen sehr großen Geldbetrag auf der Grundlage ihrer jeweiligen Prozentsätze auf mehrere Aktien verteilen müssen. Zum Beispiel:

  • Aktie A: 50,5 %
  • Aktie B: 30,3 %
  • Aktie C: 19,2 %

Die Anforderungen sind:

  • Führen Sie Berechnungen in Cent durch, um Gleitkommafehler zu vermeiden.
  • Verteilen Sie die restlichen Cent nach der ersten Rundung gerecht.
  • Rechnen Sie die endgültigen Zuteilungen mit zwei Dezimalstellen wieder in Dollar um.

Die Lösung

Mithilfe der big.js-Bibliothek können wir diese Herausforderungen mit Arithmetik beliebiger Genauigkeit bewältigen. Hier ist die Komplettlösung:

1. Eingaben initialisieren und Prozentsätze in Verhältnisse umwandeln

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. Berechnen Sie die anfängliche Zuteilung in Cent

Rechnen Sie den Gesamtbetrag in Cent um und führen Sie eine anfängliche Rundung durch:

  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. Verbleibende Cents neu verteilen

Berechnen Sie die übriggebliebenen Cent und verteilen Sie diese gerecht anhand der Restbeträge:

  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. Zurück in Dollar umrechnen

Zuletzt wandeln Sie die Zuweisungen wieder in Dollar um:

  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;
}

Beispielverwendung

So können Sie die allocateMoney-Funktion verwenden, um Gelder auf Aktien aufzuteilen:

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)}`);

Ausgabe für das Beispiel

Für die angegebenen Eingaben lautet die Ausgabe:

Allocation:
{
  'Stock A': '623456784512345.67',
  'Stock B': '374074070707407.41',
  'Stock C': '237037034903703.70'
}
Total Allocated: 34567890123456.78

Wichtige Erkenntnisse

  1. Präzise Arithmetik mit big.js:
    Die big.js-Bibliothek sorgt für Genauigkeit, indem sie Gleitkommafehler vermeidet.

  2. Gehen Sie fair mit Resten um:
    Verwenden Sie gebrochene Reste, um übrig gebliebene Einheiten deterministisch und gerecht zu verteilen.

  3. Gesamtsummen abgleichen:
    Stellen Sie nach allen Anpassungen sicher, dass die Gesamtzuteilung dem ursprünglichen Betrag entspricht.

  4. Skalierbar für große Werte:
    Dieser Ansatz funktioniert problemlos bei sehr großen Beträgen und eignet sich daher für Finanz- und Ressourcenzuweisungsprobleme.

Mit dieser Methode können Sie in jedem Szenario, das eine hohe numerische Genauigkeit erfordert, präzise und faire Zuteilungen erzielen.

Das obige ist der detaillierte Inhalt vonPräzise Zuordnungen mit Big.js: Umgang mit Rundungen und übrig gebliebener Umverteilung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn