我处于std::vector<double>
的情况,但我希望其中一些双打“没有”/“不存在”。这是如何在C ++中完成的?我们可以放心地假设所有“正常”双打对我的目的都不是负面的。
我应该让-1(或一些否定的)表示“什么都没有”?这听起来不是很优雅。
我应该创建一个带有“无”bool成员的Double类吗?这可能有效,但看起来相当冗长和丑陋。
我应该创建一个Double类并创建一个“NoDouble:public Double”子类吗?这听起来更糟。
任何想法都会受到赞赏。
答案 0 :(得分:5)
如果您有IEEE浮点运算,则使用std::numeric_limits<double>::quiet_NaN()
作为“无”的值。要检查d
是否为“无”,请使用isnan(d)
。仅当d != d
为NaN时,d
才为真。 NaN的问题在于,当进行有缺陷的计算时可以得到它,例如将零除零或从负数取平方根。任何使用NaN的计算也会导致NaN。
如果您碰巧使用提升,则可以使用boost::optional<double>
向NaN一侧添加其他级别的无法使用。然后你有两个不好的状态:无效的数字和缺少的数字。 Boost包含许多有用的库,因此无论如何它都是值得使用的工具。
如果你需要几个可能的原因,为什么它“没有”,那么使用特殊的错误类而不是double。 Fallible是由颇受好评的作者Barnton和Nackman发明的 “科学与工程C ++”一书。
您提到可能没有负数。在这种情况下,将双重包装进入课堂。你所拥有的不是技术上正常的双倍,所以你的课程可以增加它的限制。
答案 1 :(得分:1)
您可以使用std::vector<double *>
。 NULL指针表示空槽或值。
答案 2 :(得分:1)
你想要做的是保持矢量相同,但也使用bool矢量,然后将其包装在一个类中。
在适当的编译器上使用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]; }
};
我希望能做到。似乎是能够使用所有可能的double值的最佳方法,并且在使用最少内存和使用最佳内存对齐时也知道它是否为NULL。向量是C ++库中的一个特殊化模板,因此每个bool实际上只能得到1位。