C/ c++ NaN或布尔值

C/C++ NaN or boolean?

本文关键字:布尔值 NaN c++      更新时间:2023-10-16

我必须保持一个双值缓存。使用后,应使其失效。两个选择

一种是添加布尔标志,当缓存值为好的时候设置为true,当缓存值被使用的时候设置为false,当缓存值为假的时候重新计算并重新填充。

第二个更有趣-我可以将其保留为双值,并使用NaN作为无效/需要召回标志。

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

有反对意见吗?对效率有什么想法吗?

使用布尔值,否则当您计算的双精度实际上是NaN(由于计算)时,您将最终遇到一些有趣的问题/错误。如果你依赖NaN作为"我已经使用了那个值"的信号,那么你将无法区分"有效的"未使用NaN的情况。

更不用说这样的语义重载会导致将来的代码读者(甚至是几个月后的你自己)在试图破译这种巧妙的用法时挠头。: -)

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

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

我怀疑效率会有区别,但是带布尔标志的代码会更容易读:

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

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

应该指出的另一件事是IEEE nan可以有不同的值。它们的指数必须全为1,但尾数可以是任何数,但不能全为0。这意味着您可以使用"特殊"nan来区分作为计算结果产生的nan,或者如果您需要具有两种以上状态的标志,甚至可以使用不同类型的nan。