基于思维惯性, 一般我们会直接利用语言的强制类型转换, 将浮点数转成整数. 事实上, 强制转换在计算机内部的实现相当于直接抹零, 而浮点数经过运算后, 往往不能准确地表示整数, 这会导致严重的问题, 特别是涉及到钱的时候.
例如,
double f = 9.99999; int a = (int)f; printf("%f, %d/n", f, a);
输出:
9.999990, 9
不要纠结 f=9.99999 是怎么得来的, 你只要记住, 浮点数经过计算后, 很可能就会出现非常小的误差, 这些误差打印出来就能看出区别.
但是, 在这种情况下, 如果没有误差的情况下, f 应该等于 10. 所以, 一旦你想要将浮点数转成整数时, 绝对不能直接强制类型转换, 而是要先定一个最大误差值 df, 将浮点数加上这个最大误差 df 之后, 再强制转换类型.
这个最大误差值怎么来? 就是你对计算过程精度丢失的分析. 在某些正常情况, 你可以设 df=0.001. 但具体需要你分析.
所以, 正确的代码是:
double df = 0.001; double f = 9.99999; int a = (int)(f + df); printf("%f, %d/n", f, a);
最经典的就是元转成分, 一般人是这样的:
// 假设元的数值是通过网络传输的, 以字符串文本的形式 double yuan = atoi("1.13"); int fen = (int)(yuan * 100); printf("%d/n", fen);
结果输出是
原因是 1.13 无法精确表示, 在计算机内部只能表示到大约 112.9999999999999858. 强制类型转换, 就是直接抹零, 所以结果就错了.
正确的做法是:
// 假设元的数值是通过网络传输的, 以字符串文本的形式 double yuan = atoi("1.13"); double df = 0.001; int fen = (int)(yuan * 100 + df); printf("%d/n", fen);