我正在编写一个由while循环组成的程序,它读取两个双打并打印它们.该程序还会打印较大的数字和较小的数字.
这是我到目前为止的代码.
int main()
{
// VARIABLE DECLARATIONS
double a;
double b;
while (a,b != '|') //WHILE A & B DO NOT EQUAL '|'
{
cin >>a >>b;
cout << a << b << "\n" ;
if (a<b) //IF A<B: SMALLER VALUE IS A
cout << "The smaller value is:" << a << endl
<< "The larger value is:" << b << endl ;
else if (b<a) //ELSE IF B<A
cout << "The smaller value is:" << b << endl
<< "The larger value is:" << a << endl ;
else if (b==a)
cout << "The two numbers you entered are equal." << "\n" ;
}
}
Run Code Online (Sandbox Code Playgroud)
如果两个数字相差小于1.0/10000000,则下一步是让程序写出"数字几乎相等".我该怎么做?
Mic*_*eyn 25
这是我如何测试平等,没有"软糖因素":
if (
// Test 1: Very cheap, but can result in false negatives
a==b ||
// Test 2: More expensive, but comprehensive
std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon())
std::cout << "The numbers are equal\n";
Run Code Online (Sandbox Code Playgroud)
说明
第一个测试是一个简单的比较.当然,我们都知道,可能会导致比较双精度值在他们被认为是不相等的,即使它们在逻辑上是等价的.
双精度浮点值可以保存一个数字的最重要的十五位数(实际≈15.955位数).因此,如果(大约)它们的前十五个数字匹配,我们想要调用两个值相等.换句话说,如果它们在彼此的一个缩放的epsilon内,我们希望将它们称为相等.这正是第二次测试计算的内容.
您可以选择添加比单个缩放epsilon更多的余地,因为迭代计算会导致更多重要的浮点误差.为此,请在第二个测试的比较右侧添加一个错误因子:
double error_factor=2.0;
if (a==b ||
std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*
error_factor)
std::cout << "The numbers are equal\n";
Run Code Online (Sandbox Code Playgroud)
我不能给你一个固定值的error_factor,因为这将取决于错误的所爬的到您的计算量.但是,通过一些测试,您应该能够找到适合您应用的合理值.千万记住,添加仅基于猜测的(任意)误差因素将让你右后卫蒙混因素领土.
摘要
您可以将以下测试包装到(n内联)函数中:
inline bool logically_equal(double a, double b, double error_factor=1.0)
{
return a==b ||
std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*
error_factor;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22216 次 |
| 最近记录: |