汇率精度不同于金额精度
USD 金额可以显示两位小数,而用于计算的汇率可能需要更多位。为匹配货币显示格式而截短汇率,会改变每次换算的输入值。
使用示例 EUR 兑 USD 汇率 1.08765 换算 EUR 250,舍入前得到 USD 271.91250,保留两位小数为 USD 271.91。如果先将汇率舍入为 1.09,则得到 USD 272.50:显示结果相差 59 美分。
银行家舍入法处理恰好处于中点的值
当待舍入值恰好处于两个相邻可保留值的中点时,银行家舍入法会选择最后一位保留数字为偶数的那个值。保留两位小数时,1.005 变为 1.00,1.015 变为 1.02。这与中点值一律向上舍入的规则不同。
这些是精确的十进制示例。略高于或略低于中点的值都不属于中点情形。舍入模式必须明确纳入计算规则,不能取决于格式化函数碰巧采用的规则。
直接解析十进制字符串
Python 的 decimal 模块可以从字符串构造十进制值,并将结果量化为指定增量。下面的本地示例模拟两位小数的银行家舍入金额计算;它不会获取实时汇率。
from decimal import Decimal, ROUND_HALF_EVEN, localcontext
with localcontext() as ctx:
ctx.prec = 40
amount = Decimal("250.00")
rate = Decimal("1.08765")
result = (amount * rate).quantize(
Decimal("0.01"), rounding=ROUND_HALF_EVEN
)
print(result) # 271.91选择货币的最小单位
不要对每种目标货币都采用两位小数。Narwhal 的换算操作使用目标货币的 ISO 4217 最小单位。例如,文档中的 USD 兑 JPY 响应返回以整日元表示的换算金额。
使用当前货币元数据或换算端点返回的金额。现金面额舍入、商户显示规则和会计政策可能提出额外要求;这些应作为独立于汇率精度的明确选择。
避免不必要的精度损失
通过二进制浮点数转换十进制字符串,可能在十进制库看到它之前丢失信息。在 API 边界保留原始字符串,并为最大支持金额和汇率选择足够的十进制工作精度。
- 保留接收的汇率字符串,以便审计和重现。
- 在工作精度下进行中间乘除;只对最终金额舍入一次。
- 指定舍入模式和目标增量。
- 只为显示进行格式化,绝不要把格式化标签重新用于计算。
使用相同输入进行核对
如果本地计算与 Narwhal 的 converted 字段不同,请比较输入金额、完整返回汇率、目标最小单位和舍入模式。在认定结果错误前,先检查这些项目。
即使没有点差,将舍入后的金额换回原货币也可能损失少量金额。对于批量计算,逐行舍入后求和的结果,也可能不同于先汇总未舍入的数值再统一舍入的结果。请选择应用所需的规则,并保持记录一致。
来源与参考
发布于 。最近核查于 。

