我正在编写一个由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" ;
}
}
如果两个数字相差小于1.0 / 10000000,则下一步是让程序写出“数字几乎相等”。我该怎么做?
答案 0 :(得分:24)
以下是我如何测试平等,没有“软糖因素”:
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";
<强>解释强>
第一个测试是一个简单的比较。当然,我们都知道,比较双精度值可能会导致它们被认为是不相等的,即使它们在逻辑上是等价的。
双精度浮点值可以保存数字的最重要的十五位数(实际为≈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";
我无法为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;
}
答案 1 :(得分:11)
std::abs(a - b) < 0.000001
当然,用你认为“差不多”的东西替换常数。
答案 2 :(得分:4)
只测试它们是否相差少于该数量:)
if ( std::abs(a - b) < 1.0 / 10000000 )
cout << "The numbers are almost equal.\n";
答案 3 :(得分:2)
if (a * 1.0000001 > b && a < b*1.0000001)
您可以添加错误值(1.0 / 10000000.0),但通常最好使用乘数,因此比较的精确度相同。
答案 4 :(得分:1)
abs(a - b) < 1.0 / 10000000
答案 5 :(得分:1)
如果你想用a和b来扩展测试,你可以尝试测试abs(a / b-1)&lt; e,其中e是你最喜欢的微小数字,比如0.001。但是这个条件实际上在a和b中是不对称的,所以可以说a接近b,但b不接近a。那会很糟糕。最好做abs(log(a / b))&lt; e,再次,e是你最喜欢的小号码。但是对数提供了额外的计算,更不用说到处都是可怕的本科生了。
答案 6 :(得分:1)
我建议使用以下文章:new link
(过时的链接 - &gt; Comparing floating point numbers)
答案 7 :(得分:1)
我也在读这本书,因为我们没有达到std :: abs,我做了类似的事情:
int main()
{
double i1,i2;
while(cin>> i1 >> i2){
if (i1<i2) {
if ((i2-i1)<=0.0000001) cout << "Almost equal!"<<endl;
else cout << "the smaller value is: "<< i1 << " the larger value is: " << i2 <<endl;
}
if (i1>i2) {
if ((i1-i2)<=0.0000001) cout << "Almost equal!"<<endl;
else cout << "the smaller value is: "<< i2 << " the larger value is: " << i1 <<endl;
}
else if (i1==i2) cout << "the value : "<< i1 << " And the value : " << i2 << " are equal!"<<endl;
}
}