【问题标题】:C++ add values of a vector that might contain NaN valuesC++ 添加可能包含 NaN 值的向量的值
【发布时间】:2022-11-29 23:52:39
【问题描述】:

我是 C++ 菜鸟。

我想要做的是对双精度向量的值求和(我们称它为x)并忽略任何 NaN 值。我试图查找它,但我找不到任何具体引用如果向量包含任何 NaN 值会发生什么的内容。

例如。:

// let's say x = [1.0, 2.0, 3.0, nan, 4.0]
y = sum(x) // y should be equal to 10.0

accumulate 函数可以在这里工作吗?或者如果x包含NaN,它会返回NaN吗? for 循环是否可以在此处使用条件检查值是否为NaN(如果是,我如何检查是否为NaN?在我最了解的 Python 语言中,这种检查并不总是那么简单) .

【问题讨论】:

  • 这回答了你的问题了吗? Checking if a double (or float) is NaN in C++
  • 一旦 NaN 进入总和,它就会变粘。您需要编写自己的 sum 并使用 std::isnan 跳过 NaN 值。
  • 任何有效数字 + NaN == NaN;在执行累加之前过滤掉所有 NaN,或者在检查 std::isnan 时在循环中手动求和。您还可以将 std::accumulate 与您的自定义二元运算符一起使用,但要使此运算符实现稳健,您需要对 lhs 和 rhs 进行不必要的检查。

标签: c++ nan stdvector


【解决方案1】:

如果传递的浮点值不是数字,则std::isnan 返回true。您必须将此检查添加到所有函数以避免在您的计算中包含 NAN。例如sum

constexpr auto sum(auto list) {
    typename decltype(list)::value_type result = 0;

    for (const auto& i : list) {
        if (!std::isnan(i)) { // < - crucial check here
            result += i;
        }
    }
    return result;
}

Demo:

int main() {
    auto list = std::array{ 1.0f, 2.0f, 3.0f, NAN };
    std::cout << sum(list); //prints out 6
}

【讨论】:

    【解决方案2】:

    您可以将 std::accumulate 与自定义求和操作一起使用。

    const std::vector<double> myVector{1.0, 2.0, 3.0, std::nan("42"), 4.0};
    
    auto nansum = [](const double a, const double b)
    {
      return a + (std::isnan(b) ? 0 : b);
    }
    
    auto mySum = std::accumulate(myVector.begin(), myVector.end(), 0, nansum);
    

    【讨论】:

    • 文档中提到的典型错误:如果您对具有一些小数值的向量运行此操作,您的总和将被转换为 int。正确版本:std::accumulate(myVector.begin(), myVector.end(), 0.0, nansum);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2019-11-13
    • 2018-07-29
    • 1970-01-01
    • 2012-03-11
    • 2011-11-02
    相关资源
    最近更新 更多