2016-12-08

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

Views: 23123 | 4 Comments

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

例如,

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 = atof("1.13");
int fen = (int)(yuan * 100);
printf("%d\n", fen);

结果输出是

112

原因是 1.13 无法精确表示, 在计算机内部只能表示到大约 112.9999999999999858. 强制类型转换, 就是直接抹零, 所以结果就错了.

正确的做法是:

// 假设元的数值是通过网络传输的, 以字符串文本的形式
double yuan = atoi("1.13");
double df = 0.001;
int fen = (int)(yuan * 100 + df);
printf("%d\n", fen);

Related posts:

  1. 蛇形遍历数组
  2. SIP报文Via和Contact的区别
  3. 150行C代码的comet服务器
  4. WordPress开发指南
  5. 构建C1000K的服务器(1) – 基础
Posted by ideawu at 2016-12-08 21:15:32

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

Leave a Comment