2

为什么“2=”输出会给出令人惊讶的结果,请说明一下。在这种情况下 double 有什么问题。

double 值除法的任何约束。

在 c++ 中是否有任何选项可以避免此类事情。

#include<iostream.h>
#include<iomanip.h>
#include<math.h>
int main()
{
    double d1,d2,d3,d4,d5;
double d = 0.010000;

d1 = 1000000.28;
d2 = 10000000.28;
d3 = 100000000.28;
d4 = 1000000000.28;
d5 = 10000000000.28;

cout.precision(15);

cout<<"1="<<floor(d1/d)<<endl;
cout<<"2="<<floor(d2/d)<<endl;
cout<<"3="<<floor(d3/d)<<endl;
cout<<"4="<<floor(d4/d)<<endl;
cout<<"5="<<floor(d5/d)<<endl;

return 0;
  }

 o/p
 ====
1 = 1000000.28;
2 = 10000000.27;
3 = 100000000.28;
4 = 1000000000.28;
5 = 10000000000.28;
4

2 回答 2

7

首先,程序的输出与您在问题中写的不同。输出是:

1=100000028
2=1000000027
3=10000000028
4=100000000028
5=1000000000028

不是:

1 = 1000000.28;
2 = 10000000.27;
3 = 100000000.28;
4 = 1000000000.28;
5 = 10000000000.28;

其次,当你写的时候double d = 0.010000d没有设置为 .01。它被设置为一个可表示为的接近值double。(在良好的 C++ 实现中,它设置为最接近的可表示值。)在您的 C++ 实现中,double最有可能是 IEEE-754 64 位二进制浮点值,最接近 0.01 的可表示值是 0.01000000000000000020816681711721685132943093776702880859375。

同样,当您编写 时d2 = 10000000.28,d2 未设置为 10000000.28。最接近的可表示值是 10000000.27999999932944774627685546875。

当您将这些除以时,您会得到一个大约但略小于 1000000028 的数字。除法的结果四舍五入double为 1000000027.99999988079071044921875。当你取floor那个时,分数被截断,留下 1000000027。

避免或处理这些问题需要了解浮点运算以及您要执行的特定计算。在这种情况下,我们需要知道您为什么要使用floor.

于 2013-07-29T15:26:01.190 回答
0

答案很复杂,正如 WhozCraig 的评论和他链接的文件所表明的那样。

我能给出的最简短的答案是将浮点数视为非常接近十进制对应物(c++ 没有十进制数据类型)。

更容易理解这一点的方法是通过 Jon Skeet 在http://tekpub.com/blogs/video-releases/7964989-mastering-c-4-0-with-jon-skeet-7-decimals-上的精彩视频和浮点数。为了清楚起见,这是非常值得入场的。该视频特定于 c#,但概念相同。在观看视频之前,我从来不知道存在这个问题。

于 2013-07-29T15:30:33.107 回答