C / C ++ NaN还是布尔值?

时间:2015-09-24 19:12:37

标签: c++ fpu

我必须保留一个双值缓存。使用后,它应该无效。两种选择

一种是在缓存值良好时添加布尔标志true,在使用时将其设置为false,当flag为false时,重新计算并重新填充。

第二个更有趣 - 我可以将它保持为double值并使用NaN作为无效/需要重新标记。

double get() const {
    if (!isnan(_value)) {
        double t = _value;
        _value = std::numeric_limits<double>::quiet_NaN;
        return t;
    }
}

对此有何异议?对效率的任何想法?

3 个答案:

答案 0 :(得分:6)

使用布尔值,否则当你的计算结果实际上变成NaN(由于计算)时,你将会遇到一些有趣的问题/错误。如果您依赖NaN作为“我已经使用过该值”的信号,那么在“有效”未使用的NaN的情况下,您将无法区分。

更不用说这样的语义重载将导致未来的代码读者(即使是你自己从现在开始的几个月)试图破译那些聪明的用法。 ; - )

通常,重载变量的含义是一种不好的做法。起初看起来可能很可爱,但它不可避免地会造成更多伤害。

效率而言 - 我真的建议你先测量,然后再担心优化。我敢打赌,一旦你运行测试,你会发现速度差异远低于CPU温度波动引起的性能噪音。

答案 1 :(得分:3)

我怀疑效率会有所不同,但带有布尔标志的代码会更具可读性:

double get() const {
    if (!_cached)
        _value = recalculate();
    _cached = !_cached;
    return _value;
}

答案 2 :(得分:0)

我认为值得指出的是,nan可以是更有效的解决方案,最大的优势在于您使用的内存少于标记(由于对齐,其开销可能超过每个双字节1个字节) )。这意味着如果你需要读取大量内存,它也可能会更快。

应该指出的另一件事是IEEE nans可以有不同的值。他们的指数必须是全部,但尾数可以是除了全零之外的任何东西。这意味着您可以使用&#34;特殊&#34; nan用于区分计算结果,或者如果需要一个包含两个以上状态的标志,则使用不同类型的nans。