有什么区别:
if( a == b )
以及
if( qFuzzyCompare(a, b) )
假定变量a和b为:
a = 1234.5678 b = 1234.5678
注意:我这样问是因为我在比较Qt中的双精度时遇到了麻烦,我想了解qFuzzyCompare是如何工作的。
qFuzzyCompare
llycmphe1#
qFuzzyCompare()的官方文档并没有真正解释为什么要使用它,但一般来说比较浮点值被认为是一种不好的做法,因为两个看似相同的浮点变量可能会因为舍入误差而不同。您可以阅读更多关于这个和其他浮点变量here的陷阱的信息。当查看Qt5.6.0附带的qFuzzyCompare()的double和float的源代码时(按住CTRL键并单击函数,在QtCreator中查看此代码),可以推断 * 它试图减少不准确的可能性,从而妨碍相等性测试 *:
qFuzzyCompare()
Qt5.6.0
QtCreator
Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) Q_REQUIRED_RESULT Q_DECL_UNUSED; Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2))); } Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) Q_REQUIRED_RESULT Q_DECL_UNUSED; Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) { return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2))); }
7gyucuyw2#
除了上面解释的为什么你通常不想比较浮点数和==的答案之外,请注意**qFuzzyCompare可能仍然没有达到你的期望**:
==
Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2))); }
注意它是如何将p1和p2之间的差与最小数量级的元素进行比较的,一般来说这是有意义的,因为什么是可忽略的取决于手头数字的规模。问题是,以下内容将评估为false:
p1
p2
qFuzzyCompare(0.0, 1e-16) // false :/
这两个数字之间的差值虽然很小(对于双精度数,小于机器epsilon),但仍然大于0.0;因此测试将失败,即使人们合理地期望它通过。如果你能定义一个合理的SMALL_VALUE,这应该是一个足够通用的解决方案:
SMALL_VALUE
qFuzzyCompare(p1, p2) || qAbs(p1 - p2) < SMALL_VALUE
2条答案
按热度按时间llycmphe1#
qFuzzyCompare()
的官方文档并没有真正解释为什么要使用它,但一般来说比较浮点值被认为是一种不好的做法,因为两个看似相同的浮点变量可能会因为舍入误差而不同。您可以阅读更多关于这个和其他浮点变量here的陷阱的信息。当查看
Qt5.6.0
附带的qFuzzyCompare()
的double和float的源代码时(按住CTRL键并单击函数,在QtCreator
中查看此代码),可以推断 * 它试图减少不准确的可能性,从而妨碍相等性测试 *:7gyucuyw2#
除了上面解释的为什么你通常不想比较浮点数和
==
的答案之外,请注意**qFuzzyCompare
可能仍然没有达到你的期望**:注意它是如何将
p1
和p2
之间的差与最小数量级的元素进行比较的,一般来说这是有意义的,因为什么是可忽略的取决于手头数字的规模。问题是,以下内容将评估为false:
这两个数字之间的差值虽然很小(对于双精度数,小于机器epsilon),但仍然大于0.0;因此测试将失败,即使人们合理地期望它通过。
如果你能定义一个合理的
SMALL_VALUE
,这应该是一个足够通用的解决方案: