2.7 舍入误差
大多数浮点数只能大致正确地表示。有些数字,如果不是特别大的整数,可以准确地表示。但循环小数(如 1/3)和无理数(如 π)不能准确地表示。为表示这些数字,计算机必须将其舍入到最接近的浮点数。
所需数字和实际得到的浮点数之间的差称为舍入误差(rounding error)。例如,以下两条语句应该是等价的:
System.out.println(0.1 * 10);System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1+ 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
但在很多计算机上,它们的输出如下:
1.00.9999999999999999
原因是 0.1 在十进制中为有限小数,但在二进制中为循环小数,因此其浮点数表示只是近似的。将近似值相加会逐渐累积舍入误差。
在很多应用领域,如计算机图形学、加密、统计分析和多媒体渲染,使用浮点数算术利大于弊。但如果要求绝对精确,应使用整数。例如,查看余额为 123.45 美元的银行账户:
double balance = 123.45; // 可能存在舍入误差
在这个示例中,随着不断地对变量执行算术运算(如存款和取款),它存储的值将不再准确。这可能会激怒顾客,甚至引发诉讼。为避免这种问题,可以用整数来表示余额:
int balance = 12345; // 美分数
只要美分数不超过变量 int 可表示的最大值(约 20 亿),就可以使用这种解决方案。
