0

我的情况是,我有一个std::vector<double>,但我希望其中一些双打是“无”/“不存在”。这是如何在 C++ 中完成的?我们可以放心地假设所有“正常”双打对我来说都不是负面的。

我应该让-1(或一些负数)表示“无”吗?这听起来不太优雅。

我应该创建一个带有“无”布尔成员的 Double 类吗?这可以工作,但看起来相当冗长和丑陋。

我应该创建一个 Double 类并创建一个“NoDouble:public Double”子类吗?这听起来更糟。

任何想法,将不胜感激。

4

3 回答 3

5

如果您有 IEEE 浮点运算,则将std::numeric_limits<double>::quiet_NaN()其用作“无”的值。要检查是否d为“无”,请使用isnan(d). 也d != d只有当d为 NaN 时才为真。NaN 的问题在于,在进行有缺陷的计算(例如将零除以零或从负数取平方根时)可能会得到它。使用 NaN 的任何计算也使用 NaN。

如果您碰巧使用了 boost,您可以使用boost::optional<double>它在 NaN 一侧添加其他级别的不可用性。那么你有两种不好的状态:无效号码和丢失号码。Boost 包含许多有用的库,因此无论如何它都是值得的工具。

如果您需要附加几个可能的原因来说明为什么它“什么都没有”,那么请使用特殊的易错类而不是双精度类。Fallible 是 Barnton 和 Nackman 发明的,他们是备受赞誉的“科学与工程 C++”一书的作者。

你提到可能没有负数。在这种情况下,将双精度封装到类中。你所拥有的不是技术上正常的双倍,所以你的班级可以增加限制。

于 2013-02-19T23:53:00.157 回答
1

你可以使用std::vector<double *>. NULL 指针将指示空槽或值。

于 2013-02-19T23:55:48.150 回答
1

您要做的是保持向量相同,但也使用布尔向量,然后将其包装在一个类中。

在体面的编译器上使用 bool 的向量应该优化为每个布尔值 1 位,这样应该可以摆脱你的空间问题。

class MyNullable {
public:
  double value;
  bool is_null;  
};

class NullableDoubles {
public:
  std::vector<double> values;
  std::vector<bool> nulls;
  void push_back(double d, bool is_null) {
    values.push_back(d);
    nulls.push_back(is_null);
  }
  MyNullable GetValue(int index) {
    MyNullable result;
    result.value = values[index];
    result.is_null = nulls[index];
    return result;
  }
  bool IsNull(int index) { return nulls[index]; }
  bool MakeNull(int index) { nulls[index] = false; }
};

而且我相信您可以看到将其包装在一个或两个模板中然后制作任何可以为空的列表的价值(不是双关语)。

template <class T>
class NullablesClass {
public:
  std::vector<T> values;
  std::vector<bool> nulls;
  void push_back(T d, bool is_null) {
    values.push_back(d);
    nulls.push_back(is_null);
  }
  MyNullable GetValue(int index) {
    MyNullableT<T> result;
    result.value = values[index];
    result.is_null = nulls[index];
    return result;
  }
  bool IsNull(int index) { return nulls[index]; }
  bool MakeNull(int index) { nulls[index] = false; }
  T GetValue(int index) { return values[index]; }
};

我希望可以做到。似乎是能够使用所有可能的双精度值并且在使用最少内存和使用最佳内存对齐方式时知道它是否为 NULL 的最佳方法。向量是 C++ 库中的一个特化模板,因此您实际上应该只获得每个布尔值 1 位。

于 2013-02-20T00:27:15.997 回答