把double类型小数点后面的数字输出问题例如把21.999999后面的小数部分输出,即999999,用如下代码实现时如果
把double类型小数点后面的数字输出问题
例如把21.999999后面的小数部分输出,即999999,用如下代码实现时如果是待处理的数据小于2时可以正确输出,但一旦大于二就陷入for循环出不来。
- C/C++ code
int main(){ double d1=1.999999; double d2,d3; int i1=int(d1); d2=d1-i1; for(d3=d2-int(d2);d3!=0;) { d2*=10; d3=d2-int(d2); } cout<<d2<<endl; return 0;}[解决办法]
http://topic.csdn.net/u/20121007/12/2f645c39-8123-448d-8c88-2c27fed0b812.html
[解决办法]
不太明白这样的代码有何意义,可以参考IEEE754(http://en.wikipedia.org/wiki/IEEE_floating_point)浮点数规格。
[解决办法]
这个似乎要了解编译器对浮点数如何处理的,你在for循环内涉及到浮点数的计算,并不能保证d3 = d2-int(d2);后的d3结果与你期望的一致(可以参考浮点数的存储格式),这样就会导致d3始终不会为0,所以陷入死循环。小于2的浮点数也会陷入的,完全看你给定的数是不是凑巧在计算过程中出现过d3为0的情况。个人理解,仅供参考。
[解决办法]
用字符串处理比较靠谱。
- C/C++ code
#include <iostream>#include <cmath>#include <cstring>#include <cstdio>using namespace std;int main(){ double d1 = 1.999999; double fractpart, intpart; char buf[80] = { 0 }; fractpart = modf(d1, &intpart); sprintf(buf, "%lf", d1); strtok(buf, "."); cout << strtok(NULL, ".") << endl; return 0;}
[解决办法]
不是大于2的原因,下面这个1.999就不行
给个例子,你就知道为什么不能这样做了
这里你需要的是1.999,但实际上机器只能给你一个近似值
在整数溢出前能否得到一个看起来正确的结果,完全没有保障
- C/C++ code
double f=1.999; for(int i=0;i<12;++i) { printf("%48.32f\t%12d\n",f,int(f)); f*=10; }
[解决办法]
楼主应该思考一个问题
实数有无限个。浮点数只有有限个。能等同起来吗?
1个浮点数就是占80个字节,也只能表示有限个实数
这有限个浮点数只能对应有限个实数,其它的实数只能用它们近似表示
你任意给一个实数,机器(IEEE浮点数编码)给出的,可能刚好是准确的该数,但更可能的却是一个近似值
即便该实数能准确表示,小数点移动一位后的实数,却又未必能 