NumberFormatter处理Float与Double值时的halfUp舍入不一致问题
Float精度限制导致的舍入差异
这是Float精度低于Double造成的,和NumberFormatter的舍入逻辑无关——它对所有数值类型的处理规则是一致的,问题根源在浮点数的二进制存储特性上。
十进制的1.635无法被二进制浮点数精确表示,无论是Float还是Double,存储的都是近似值:
- Float是32位浮点数,精度有限,
Float(1.635)实际存储的数值略小于1.635(用高精度打印会得到1.6349999904632568)。 - Double是64位浮点数,精度更高,
Double(1.635)实际存储的数值略大于1.635(高精度打印结果为1.6350000000000001)。
NumberFormatter的halfUp舍入规则是:保留两位小数时,看第三位小数对应的数值是否≥0.005,是则进位。对于Float的近似值来说,它比1.635小一点,第三位小数对应的数值不足0.005,所以舍去后得到1.63;而Double的近似值比1.635大一点,满足进位条件,所以得到1.64。
你可以用以下代码验证实际存储的数值:
print(String(format: "%.20f", Float(1.635))) // 输出 1.63499999046325683594 print(String(format: "%.20f", Double(1.635))) // 输出 1.63500000000000013323
如果需要精确处理十进制数值,建议用Decimal类型替代Float/Double,它专门为十进制运算设计,不会出现这类精度问题:
print(Decimal(string: "1.635")!.halfUpFormatted) // 输出 1.64
内容的提问来源于stack exchange,提问作者Hollycene
相关产品推荐
相关产品推荐

