比较c ++中的浮点数
Comparing floats in c++
我正在通过教程学习 C++,有人告诉我在 C++ 中比较浮点数可能会非常令人困惑。例如,在下面的代码中:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == 1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
我会得到“不等于”。我同意这一点。导师告诉我们,如果我们需要比较浮点数,我们可以使用 > 到最近的数字。 (这不是很精确)。我在 google 中搜索了不同的方法来比较浮点数,并且我得到了很多复杂的方法。
然后我自己创建了一个程序:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == (float)1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
像上面那样进行类型转换后,我得到了“等于”。
我想知道的是,我是否应该在我的所有程序中都使用上述方法来比较浮点数?这有什么缺点吗?
注意 :我知道一个数字在内存中是如何精确表示的,以及 0.1 + 0.2 !- 0.3 是如何描述的SO Question。我只是想知道我可以用上面的方法检查两个浮点数是否相等吗?
在某种程度上,第二个示例起作用的原因纯属偶然。
需要考虑的一些因素:
当比较的两边都是float
类型时,编译器可能更有可能“优化掉”比较,这样它就发生在编译过程中。它可以查看文字并意识到这两个数字在逻辑上是相同的,即使在运行时它们可能在较低的精度级别上有所不同。
当比较的两边都是 float
类型时,它们具有相同的精度,因此如果您以相同的方式创建值(此处为文字) , 较低精度水平的任何错误都可能相同。当其中之一是 double
时,您在末尾会有额外的错误位,从而导致比较失败。如果您通过 0.6 + 0.6
创建了一个,那么结果也可能不同,因为错误传播的方式不同。
一般情况下,不要依赖这个。当你的浮点数包含不能用二进制精确表示的数字时,你无法真正预测你的浮点数有多“准确”。如果您需要松散的值比较,您应该坚持使用 epsilon 范围比较(在适当的情况下),即使直接比较在没有它的情况下偶尔似乎“有效”。
如果您实际上不需要 浮动 点,一个好的方法是使用固定点。该语言中没有内置的定点类型,但这没关系,因为您可以通过一些算术简单地模拟它们。很难知道您的用例是什么,但如果您只需要一位小数,则可以存储 int decimalNumber = 12
(即将小数点移动一位),并在需要显示时除以十。两个 int
的值 12
总是比较好。
金钱就是一个很好的例子:以便士(或十分之一便士)计算,而不是以英镑计算,以避免在骗取客户现金时出现错误。
与浮点变量相比的浮点数在 C++ 中默认被视为 double
。您需要使用 f
后缀来告诉编译器该数字是浮点数而不是 double
。举个例子:
#include <iostream>
int main(void) {
float dec = 1.2;
if (dec == 1.2f)
std::cout << "Equal";
else
std::cout << "Unequal";
return 0;
}
它将产生 Equal
。 OTOH,如果你不使用 f
后缀,比较将等同于:
if (dec == 1.199999999999999956) // 1.2 converted into double
The thing I want to know is that should I use the above way to compare floats in all of my programs?
取决于上下文。相等比较很少对浮点数有用。
但是是的,无论是相等性还是关系性比较,都应该比较相同类型的浮点对象,而不是混合使用 float 和 double。
Does this have some cons?
浮点计算可能有错误。结果可能不是您所期望的。当有错误时,相等比较是没有意义的。
我正在通过教程学习 C++,有人告诉我在 C++ 中比较浮点数可能会非常令人困惑。例如,在下面的代码中:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == 1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
我会得到“不等于”。我同意这一点。导师告诉我们,如果我们需要比较浮点数,我们可以使用 > 到最近的数字。 (这不是很精确)。我在 google 中搜索了不同的方法来比较浮点数,并且我得到了很多复杂的方法。
然后我自己创建了一个程序:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == (float)1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
像上面那样进行类型转换后,我得到了“等于”。
我想知道的是,我是否应该在我的所有程序中都使用上述方法来比较浮点数?这有什么缺点吗?
注意 :我知道一个数字在内存中是如何精确表示的,以及 0.1 + 0.2 !- 0.3 是如何描述的SO Question。我只是想知道我可以用上面的方法检查两个浮点数是否相等吗?
在某种程度上,第二个示例起作用的原因纯属偶然。
需要考虑的一些因素:
当比较的两边都是
float
类型时,编译器可能更有可能“优化掉”比较,这样它就发生在编译过程中。它可以查看文字并意识到这两个数字在逻辑上是相同的,即使在运行时它们可能在较低的精度级别上有所不同。当比较的两边都是
float
类型时,它们具有相同的精度,因此如果您以相同的方式创建值(此处为文字) , 较低精度水平的任何错误都可能相同。当其中之一是double
时,您在末尾会有额外的错误位,从而导致比较失败。如果您通过0.6 + 0.6
创建了一个,那么结果也可能不同,因为错误传播的方式不同。
一般情况下,不要依赖这个。当你的浮点数包含不能用二进制精确表示的数字时,你无法真正预测你的浮点数有多“准确”。如果您需要松散的值比较,您应该坚持使用 epsilon 范围比较(在适当的情况下),即使直接比较在没有它的情况下偶尔似乎“有效”。
如果您实际上不需要 浮动 点,一个好的方法是使用固定点。该语言中没有内置的定点类型,但这没关系,因为您可以通过一些算术简单地模拟它们。很难知道您的用例是什么,但如果您只需要一位小数,则可以存储 int decimalNumber = 12
(即将小数点移动一位),并在需要显示时除以十。两个 int
的值 12
总是比较好。
金钱就是一个很好的例子:以便士(或十分之一便士)计算,而不是以英镑计算,以避免在骗取客户现金时出现错误。
与浮点变量相比的浮点数在 C++ 中默认被视为 double
。您需要使用 f
后缀来告诉编译器该数字是浮点数而不是 double
。举个例子:
#include <iostream>
int main(void) {
float dec = 1.2;
if (dec == 1.2f)
std::cout << "Equal";
else
std::cout << "Unequal";
return 0;
}
它将产生 Equal
。 OTOH,如果你不使用 f
后缀,比较将等同于:
if (dec == 1.199999999999999956) // 1.2 converted into double
The thing I want to know is that should I use the above way to compare floats in all of my programs?
取决于上下文。相等比较很少对浮点数有用。
但是是的,无论是相等性还是关系性比较,都应该比较相同类型的浮点对象,而不是混合使用 float 和 double。
Does this have some cons?
浮点计算可能有错误。结果可能不是您所期望的。当有错误时,相等比较是没有意义的。