Maison > interface Web > js tutoriel > Allocations précises avec Big.js : gestion des arrondis et de la redistribution des restes

Allocations précises avec Big.js : gestion des arrondis et de la redistribution des restes

Barbara Streisand
Libérer: 2024-12-31 17:39:08
original
1057 Les gens l'ont consulté

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

Lorsqu'il s'agit d'allocations fractionnées de gros montants, les erreurs d'arrondi et les redistributions restantes deviennent des défis importants. Ces problèmes ne se limitent pas aux calculs financiers ; ils peuvent survenir dans d'autres domaines comme la distribution des ressources, la planification des tâches ou l'allocation budgétaire. Dans cet article, nous démontrons une méthode vérifiée et testée utilisant la bibliothèque big.js en JavaScript pour obtenir des allocations précises tout en gérant efficacement les arrondis et la redistribution des restes.


Problème : répartition des fonds entre les actions

Imaginez un scénario dans lequel vous devez répartir une très grosse somme d'argent entre plusieurs actions en fonction de leurs pourcentages respectifs. Par exemple :

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

Les exigences sont :

  • Effectuez des calculs en centimes pour éviter les erreurs en virgule flottante.
  • Distribuez équitablement les centimes restants après l'arrondi initial.
  • Convertissez les allocations finales en dollars avec deux décimales.

La solution

En utilisant la bibliothèque big.js, nous pouvons relever ces défis avec une arithmétique de précision arbitraire. Voici la solution complète :

1. Initialiser les entrées et convertir les pourcentages en ratios

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);
  }
Copier après la connexion

2. Calculer l'allocation initiale en centimes

Convertissez le montant total en centimes et effectuez l'arrondi initial :

  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)
  }
Copier après la connexion

3. Redistribuer les centimes restants

Calculez les centimes restants et répartissez-les équitablement en fonction des restes fractionnaires :

  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);
  }
Copier après la connexion

4. Reconvertir en dollars

Enfin, reconvertissez les allocations en dollars :

  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;
}
Copier après la connexion

Exemple d'utilisation

Voici comment utiliser la fonction allocateMoney pour répartir les fonds entre les actions :

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)}`);
Copier après la connexion

Sortie pour l'exemple

Pour les entrées données, la sortie est :

Allocation:
{
  'Stock A': '623456784512345.67',
  'Stock B': '374074070707407.41',
  'Stock C': '237037034903703.70'
}
Total Allocated: 34567890123456.78
Copier après la connexion

Points clés à retenir

  1. Arithmétique précise avec big.js :
    La bibliothèque big.js garantit la précision en évitant les erreurs à virgule flottante.

  2. Gérer les restes de manière équitable :
    Utilisez des restes fractionnaires pour répartir les unités restantes de manière déterministe et équitable.

  3. Réconcilier les totaux :
    Après tous les ajustements, assurez-vous que l'allocation totale correspond au montant initial.

  4. Évolutif pour les grandes valeurs :
    Cette approche fonctionne parfaitement pour les montants très importants, ce qui la rend adaptée aux problèmes financiers et d'allocation des ressources.

En suivant cette méthode, vous pouvez obtenir des allocations précises et équitables dans tout scénario nécessitant une grande précision numérique.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal