Tengo una función para calcular el porcentaje de las tarifas de transacción. Para probarlo, escribí la siguiente función para garantizar que los cálculos de la tasa sean precisos. Sin embargo, la tasa calculada (1 - part/whole) * 100 está desviada por un pequeño margen de la tasa real pasada a la función.
¿Hay alguna forma de corregir el error y garantizar que la rate === calculated rate ?
PD: Redondear a un número fijo de lugares decimales no solucionaría el problema ya que la tasa puede tener un número variable de lugares decimales.
const getAmount = (amount, rate) => { const fee = amount * (rate / 100); const amountAfterFee = amount - fee; const calculatedRate = (1 - amountAfterFee / amount) * 100; return { amount, fee, amountAfterFee, rate, calculatedRate }; }; console.log(getAmount(3000, 5)); // { amount: 3000, fee: 150, amountAfterFee: 2850, rate: 5, calculatedRate: 5.000000000000004 } console.log(getAmount(3000, 6.0)); // { amount: 3000, fee: 180, amountAfterFee: 2820, rate: 6, calculatedRate: 6.000000000000005 } console.log(getAmount(3000, 7.3)); // { amount: 3000, fee: 219, amountAfterFee: 2781, rate: 7.3, calculatedRate: 7.299999999999995 } console.log(getAmount(3000, 8.12345)); // { amount: 3000, fee: 243.7035, amountAfterFee: 2756.2965, rate: 8.12345, calculatedRate: 8.123449999999998 }Está utilizando flotadores para realizar cálculos. Debido a su representación interna , puede haber problemas de precisión, como el que está enfrentando. Vea el vínculo para mas detalles.
En resumen, como parece estar manejando cálculos de moneda, su mejor opción es usar, en lugar de flotar, un tipo de datos específico como moneda.js :
const m = (amount) => currency(amount, { precision: 10 }) const getAmount = (amount, rate) => { const fee = m(amount).multiply(m(rate).divide(100)); const amountAfterFee = m(amount).subtract(fee); const calculatedRate = m(1).subtract(amountAfterFee.divide(amount)).multiply(100); return { amount, fee, amountAfterFee, rate, calculatedRate }; }; console.log(getAmount(3000, "5")); // { amount: 3000, fee: 150, amountAfterFee: 2850, rate: 5, calculatedRate: 5.000000000000004 } console.log(getAmount(3000, "6.0")); // { amount: 3000, fee: 180, amountAfterFee: 2820, rate: 6, calculatedRate: 6.000000000000005 } console.log(getAmount(3000, "7.3")); // { amount: 3000, fee: 219, amountAfterFee: 2781, rate: 7.3, calculatedRate: 7.299999999999995 } console.log(getAmount(3000, "8.12345")); // { amount: 3000, fee: 243.7035, amountAfterFee: 2756.2965, rate: 8.12345, calculatedRate: 8.123449999999998 } <script src="https://cdn.jsdelivr.net/npm/currency.js"></script>Naturalmente, hay otras opciones disponibles, como dinero.js . Cuál te conviene más depende de tu caso concreto, como siempre.