You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算Reprofiled Amount列最后一笔付款,使总额匹配RC金额并修正精度误差

解决最后一笔付款金额差额问题,确保总额与RC一致

问题背景

需要计算Reprofiled Amount列的最后一笔付款(保留两位小数),使所有付款总额与Research Costs(RC)金额完全相等,差额需加到最后一笔季度付款中。

目前将3个付款值存储在numAmounts数组:

const numAmounts = [ 106017.96, 106017.96, 106017.96 ];

当前代码计算出的最后一笔付款为106017.96999999997,经formatAsCurrency(remainningAmount, 2, 2)格式化后变为106017.96,导致所有付款总和比RC金额少1分钱,需将这1分钱补到最后一笔付款中。

原代码片段:

function formatAsCurrency(numValue, numMinimumDigits, numMaximumDigits)
{
    try
    {
        if (!numMinimumDigits || isNaN(numMinimumDigits))
        {
            numMinimumDigits = 0;
        }

        numValue = Number(numValue.toString().replace(/[^0-9.-]/g, ""));
        if (!isNaN(numValue))
        {
            if (!numMinimumDigits || numMinimumDigits <= 0)
            {
                return Number(numValue.toFixed(0)).toString();
            }
            else
            {
                return numValue.toLocaleString("en-US", { minimumFractionDigits: numMinimumDigits, maximumFractionDigits: numMaximumDigits });
            }
        }
        else
        {
            return numValue;
        }
    }
    catch (ex)
    {
        alert("Error in formatAsCurrency(): " + ex.toString());
        disableAll();
        return false;
    }
}
const RC = 424071.85;      
const numAmounts =  [ 106017.96, 106017.96, 106017.96 ];
const sum = numAmounts.reduce((acc, curr) => acc + curr, 0);
const remainningAmount = RC - sum;
console.log("remainningAmount", formatAsCurrency(remainningAmount, 2, 2));

解决方案

问题源于浮点数精度误差及格式化时的截断。需先计算精确差额,再调整最后一笔付款,确保总额完全匹配RC。

修改后的代码:

function formatAsCurrency(numValue, numMinimumDigits, numMaximumDigits)
{
    try
    {
        if (!numMinimumDigits || isNaN(numMinimumDigits))
        {
            numMinimumDigits = 0;
        }

        numValue = Number(numValue.toString().replace(/[^0-9.-]/g, ""));
        if (!isNaN(numValue))
        {
            if (!numMinimumDigits || numMinimumDigits <= 0)
            {
                return Number(numValue.toFixed(0)).toString();
            }
            else
            {
                return numValue.toLocaleString("en-US", { minimumFractionDigits: numMinimumDigits, maximumFractionDigits: numMaximumDigits });
            }
        }
        else
        {
            return numValue;
        }
    }
    catch (ex)
    {
        alert("Error in formatAsCurrency(): " + ex.toString());
        disableAll();
        return false;
    }
}

const RC = 424071.85;      
const numAmounts =  [ 106017.96, 106017.96, 106017.96 ];

// 计算当前总和并保留两位小数,消除浮点数累加误差
const sum = Number(numAmounts.reduce((acc, curr) => acc + curr, 0).toFixed(2));
// 计算RC与当前总和的精确差额
const diff = RC - sum;
// 调整最后一笔付款,保留两位小数确保精度
const adjustedLastAmount = Number((numAmounts[numAmounts.length - 1] + diff).toFixed(2));
// 更新付款数组
const adjustedAmounts = [...numAmounts.slice(0, -1), adjustedLastAmount];

// 验证调整后的总额
const total = adjustedAmounts.reduce((acc, curr) => acc + curr, 0);
console.log("调整后的付款数组:", adjustedAmounts.map(amt => formatAsCurrency(amt, 2, 2)));
console.log("验证总额:", formatAsCurrency(total, 2, 2)); // 输出应等于RC的424071.85

关键说明

  • 先将总和转为两位小数,避免浮点数累加带来的精度偏差
  • 计算RC与当前总和的精确差额,该差额即为需要补充到最后一笔的金额
  • 调整最后一笔付款后,再次转为两位小数,确保金额格式符合要求
  • 验证调整后的总额,确保与RC完全一致

内容的提问来源于stack exchange,提问作者Karim Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:10:29