转载

正确的将浮点数转成整数的方法 – 避免强制类型转换

基于思维惯性, 一般我们会直接利用语言的强制类型转换, 将浮点数转成整数. 事实上, 强制转换在计算机内部的实现相当于直接抹零, 而浮点数经过运算后, 往往不能准确地表示整数, 这会导致严重的问题, 特别是涉及到钱的时候.

例如,

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);
原文  http://www.ideawu.net/blog/archives/976.html
正文到此结束
Loading...