经得起雷劈:关于double和int/long相互转换失去精度计算错误的问题
2011-08-03 11:24
405 查看
在用C/C++做运算时,类型转换是很常见的,一般都直接用数据类型进行默认强制转化,但是这样其实是有很大问题的。
这个例子一眼看过去,很简单嘛,应该是输出201, 但是实际运行结果确是200...200和201的差距可是相当大了,足够让火箭坠毁动车被雷劈了 :)
所以,我们作为无证程序员,要写出经得起雷劈的程序,这些想当然的BUG必须是要规避的。我采用的是double转换int末位四舍五入的方法。
代码如下
这样得到的就是正确的结果了。
现在来分析根本原因:
由于浮点和整形的保存方法是完全不同的,所以double y = 2.01在内存中实际是
FF FF FF FF FF 1F 69 40
经过IEEE的标准换算过来其实是2.00999999997, 这样,乘以100后得到200.99999997,强制转换整形的算法是向下取整,这样导致结果成了200
#include <stdio.h> int main(int argc, char *argv[]) { double x = 2.01; int y = x * 100; printf("y = %d\n", y); return 0; }
这个例子一眼看过去,很简单嘛,应该是输出201, 但是实际运行结果确是200...200和201的差距可是相当大了,足够让火箭坠毁动车被雷劈了 :)
所以,我们作为无证程序员,要写出经得起雷劈的程序,这些想当然的BUG必须是要规避的。我采用的是double转换int末位四舍五入的方法。
代码如下
inline int double2int(double in) { return in > 0 ? (in + 0.5) : (in - 0.5); }
这样得到的就是正确的结果了。
#include <stdio.h> int main(int argc, char *argv[]) { double x = 2.01; int y = double2int(x * 100); printf("y = %d\n", y); return 0; }
现在来分析根本原因:
由于浮点和整形的保存方法是完全不同的,所以double y = 2.01在内存中实际是
FF FF FF FF FF 1F 69 40
经过IEEE的标准换算过来其实是2.00999999997, 这样,乘以100后得到200.99999997,强制转换整形的算法是向下取整,这样导致结果成了200
相关文章推荐
- 经得起雷劈:关于double和int/long相互转换失去精度计算错误的问题
- 关于c中 int, float, double转换中存在的精度损失问题
- 关于java中long类型的数据转换json传到前台时丢失精度问题的解决办法
- double 和 int 转换 时的精度问题
- 超级‘’傻逼‘’错误--Float和double精度问题在账户金额计算时的大坑
- c/c++ bytes与int,short,long,float,double相互转换
- 关于int类型指针和char类型指针相互转换问题
- String与int、long、float、double等相互转换
- 关于计算订单价格,转换后差一分钱的解决方法(浮点数精度问题)
- 【C语言学习趣事】_33_关于C语言和C++语言中的取余数(求模)的计算_有符号和无符号数的相互转换问题
- float和double丢失精度问题,可用Long来转换
- float和double丢失精度问题,可用Long来转换
- 关于float和double的精度问题
- char,int,long混合计算问题
- short int,int,unsigned int,long,long int,float,double等32位,64位各占几个字节的问题
- 关于java中Double类型的运算精度问题
- Swift入门(九)——String与Int、Double、Float等数字相互转换
- 编写重载函数min(),分别计算int、double、float、long类型数组中的最小树
- 关于java中Double类型的运算精度问题
- Android 中java 关于字符串与整形转换的相关问题(Invalid Int)