以双重价值划分的问题
issue in division with double values
为什么"2="输出会给出令人惊讶的结果,请解释一下。在这种情况下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;
首先,程序的输出与您在问题中所写的不同。输出为:
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.010000
时,d
不会设置为.01。它被设置为可表示为double
的闭合值。(在一个好的C++实现中,它被设置为最接近的可表示值。)在C++实施中,double
很可能是IEEE-754 64位二进制浮点值,而与.01最接近的表示值是0.01000000000000000020816681711721685132943093776702880859375。
类似地,在编写d2 = 10000000.28
时,d2不会设置为10000000.28。最接近的可表示值为10000000.279999932944774627685546875。
当你把这些除以,你得到一个大约但略小于1000000028的数字。除法的结果四舍五入为double
,为1000000027.99999988070971044921875。当你取其中的floor
时,分数会被截断,留下1000000027。
避免或处理这些问题需要了解浮点运算和要执行的特定计算。在这种情况下,我们需要知道您为什么要使用floor
。
答案很复杂,正如WhozCraig的评论和他链接的文档所示。
我能给出的最简单的答案是,将浮点数视为与十进制数非常接近的近似值(c++没有十进制数据类型)。
一个更容易理解的方法是通过Jon Skeet在http://tekpub.com/blogs/video-releases/7964989-mastering-c-4-0-with-jon-skeet-7-decimals-and-floating-points.为了清晰起见,这完全值得入场费。这个视频是特定于c#的,但概念是相同的。在看视频之前,我从来不知道这个问题存在。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- C 划分和征服方形矩阵乘法问题
- 解析格式化输入时划分单词时出现问题
- 以双重价值划分的问题