未初始化的浮点数(C++)

4
如果你想要用“未初始化”状态来初始化一个浮点数,你会选择什么值呢?(这个值容易测试且最不可能与实际值混淆)

float min = std::numeric_limits::quiet_NaN();

使用-999999. 可能会因为模糊的浮点数四舍五入而产生问题,可能会被误认为是实际值,而且看起来也很天真。

boost::optional<float> - Jarod42
3个回答

12

如果你想避免使用有效的 float 值,可以使用 NAN:

#include <limits>

....
float min = std::numeric_limits<float>::quiet_NaN();
您可以使用 std::isnan 进行检查:
#include <cmath>

....
bool not_cool = std::isnan(min);

好的,谢谢。在C99中似乎没有isnan可用,但将float与std :: numeric_limits <float> :: quiet_NaN()进行比较似乎有效。 - tru7
2
@Juan 在比较可能为NaN的值时一定要非常小心。因此,即使将myVal设置为std::numeric_limits<float>::quiet_NaN(),运行if(myVal == std::numeric_limits<float>::quiet_NaN())也始终为false。你需要一个isnan等效函数。[编辑:请参见http://ideone.com/hzFCyB] - Mike Vine
谢谢Mike,现在似乎我们处于不确定的领域 :-) - tru7
更新:在VStudio 2008中有_isnan()函数。 - tru7

5
你可以使用NAN。然而,问题是使用了未初始化的浮点变量。与整数不同,不是所有位模式都可用作浮点值。有一类特殊的“非数字”值称为信号NaN(SNaN),如果您请求处理器,则它将留意这些信号NaN,并在遇到其中一个时引发“无效操作数”异常。(毕竟,这就是为什么它被称为信号NaN的全部原因。)我建议您也使用Boost.Optional,像这样:
boost::optional<float> minValue;  // initially unset

2
Boost.Optional也是我在这种“问题”上的选择,特别是它很快就会成为std::optional<T> - Piotr Skotnicki
这个引用来自哪里?请注明出处。 - Lightness Races in Orbit
@LightnessRacesinOrbit:我在NAN中引用了该网站。 - user3414693

3
根据变量名min,您希望它尽可能大。这样,与此值的任何比较都将是较小的值,并更新您的minValue
float minValue = std::numeric_limits<float>::max();

提示:不要将变量命名为min,否则可能会遇到名称遮蔽问题。


4
当您将 std:: 加在前面时,名称遮蔽问题实际上不是问题。 - chris
我只是指一般情况下可能存在的不良行为。特别是因为每个人都喜欢使用 using namespace std,这同样糟糕。 - Cory Kramer
1
@Cyber:没错,所以不要那样做。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接