比较int和double时出错
Error while comparing a int and a double
我正在尝试制作一个计算位数的简单函数。我写了一些功能,可以完美地工作,但我被这个卡住了:
// The number I want to count the digits after the decimal
long double d=33.56;
// Going to modify d but I wan't to keep the original value
long double dTemp=d;
// v to store the part after the decimal and e the part before
long double v, e;
v=modfl(dTemp,&e);
// j is the number of digit after the decimal
int j=0;
while(dTemp!=e)
{
j++;
dTemp*=10;
v=modfl(dTemp,&e);
std::cout<<"D = "<<dTemp<<" e = "<<e<<" v = "<<v<<std::endl;
}
std::cout<<"J = "<<j<<std::endl;
输出为:
D = 335.6 e = 335 v = 0.6
D = 3356 e = 3356 v = 2.27374e-13
D = 33560 e = 33560 v = 2.27374e-12
D = 335600 e = 335600 v = 2.27374e-11
D = 3.356e+06 e = 3.356e+06 v = 2.27374e-10
D = 3.356e+07 e = 3.356e+07 v = 2.27374e-09
D = 3.356e+08 e = 3.356e+08 v = 2.27301e-08
D = 3.356e+09 e = 3.356e+09 v = 2.27243e-07
D = 3.356e+10 e = 3.356e+10 v = 2.27243e-06
D = 3.356e+11 e = 3.356e+11 v = 2.27094e-05
D = 3.356e+12 e = 3.356e+12 v = 0.000226974
D = 3.356e+13 e = 3.356e+13 v = 0.00226974
D = 3.356e+14 e = 3.356e+14 v = 0.0227051
D = 3.356e+15 e = 3.356e+15 v = 0.227051
D = 3.356e+16 e = 3.356e+16 v = 0.269531
D = 3.356e+17 e = 3.356e+17 v = 0.6875
D = 3.356e+18 e = 3.356e+18 v = 0
J = 17
但是,如果你看看输出的第2行,你会发现:
D=3356 e=3356 v=2.27374e-1
因此,dTemp等于e,while循环仍在继续。
我尝试了什么:
我想我可能是因为d无法存储所需的大数字。这就是我使用长双的原因
- 我尝试了不同类型的变量,但最终总是得到相同的结果
直接检查浮点数/双数/长双数的等式/非等式不是一个好的做法。所以我建议使用类似的东西
不相等:
while (abs(dTemp - e) > 1e-12) { ... }
相等:
while (abs(dTemp - e) < 1e-12) { ... }
"微小"数字取决于非整数的类型(浮点或固定精度实数)。M-Gregoire关于使用std::numeric_limits<double>::epsilon()
的评论听起来不错,但人们可能会再次面临问题。由于33.56不能计算为2的正和/或负幂的有限和,因此不能存储!总是有细微的差别。在内部,它是这样存储的:33.56000000000000227373675443232059478759766
(我在perl中打印,但在c++中您会得到类似的结果)。因此,您可以将这个"微小"的差值设置为一个"适当"的值,这个值足够高,可以禁用这个内部浮点格式问题。
您可以使用另一种方法。std::ostringstream
可以与操纵器setprecision
一起使用,将精度设置为"正确"数字,将数字转换为字符串,然后计算字符串中的数字。但这也不是那么简单。
我也检查了c++中的值"33.56"。参见示例代码:
#include <iostream>
#include <iomanip>
int main() {
float df = 33.56;
double dd = 33.56;
long double dld = 33.56;
std::cout << std::setprecision(50) << df << std::endl;
std::cout << std::setprecision(50) << dd << std::endl;
std::cout << std::setprecision(50) << dld << std::endl;
}
输出为:
33.560001373291015625
33.56000000000000227373675443232059478759766
33.56000000000000227373675443232059478759766
因此,在浮动1e-5可以用于间隙值的情况下,对于双1e-14,在这种情况下似乎是正确的值。
相关文章:
- 访问者访问变体并返回不同类型时出错
- 在Linux for Windows上编译C++代码时出错
- 读取文件的最后一行并输入到链接列表时出错
- 重载操作程序时出错>>用于类中的字符串 memebr
- 调用专用模板时出错"no matching function for call to [...]"
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 在Google Kick start中提交时出错
- 在c++中访问int到类对象的映射时出错
- 分段错误当我试图运行程序时出错
- 使用dynamic_cast和构造函数时出错
- CHECK(调用)函数在Google Colab中出错
- 用pybind11包装C++抽象类时出错
- 为x86而非x64编译时出错
- 从R调用C++函数并对其进行集成时出错
- 比较int和double时出错
- 在函数 c/c++ 中传递指针时出错"double** to double*"
- 将“const”作为“const double”的“this”参数传递时出错,将丢弃限定符
- 编译程序时出错C++:"error: cast from ‘double*’ to ‘int’ loses precision"
- 共享库从 void * "invalid conversion" 到 double(*) (int*) 时出错?