Kur*_*ehr 8 c++ nan infinity numeric-limits c++11
这可能是自行车脱落,但也许有一些有趣的东西让我失踪......
如果一个类初始化一个成员val,std::numeric_limits<double>::infinity()然后想要检查val是否已被更改为有效的东西(+/- inf在这里无效),这3种方法的权衡是什么,我是否错过任何其他有趣的方法来解决这个问题.(为了便于阅读,删除了const.)
bool IsInit() { return MinX != std::numeric_limits<double>::infinity(); } // a
bool IsInit() { return !std::isinf(MinX); } // b
bool IsInit() { return std::isfinite(MinX); } // c
Run Code Online (Sandbox Code Playgroud)
现在代码是C++ 03,但是如何使用C++ 11,C++ 14和C++ 17来改变选项.例如,使用C++ 17,这段代码可能就是这样std::optional<double> val.或者安静NaN是一个更安全的赌注,只是因为+/- inf在未来变得有效?
当我在阅读此代码的补丁时出现了这个问题:
为便于参考:
相关类型:
仅当变量无法以其他方式获取特殊值时,使用这些特殊值作为初始化标志才有效。就数学运算而言,无穷大并不难获得,因为溢出也会得到它。所以这可能会有问题。如果不变量只是用户无法将此浮点值设置为该值,则使用安静的 NaN(如果可用)会更容易使用。
就这三种方法而言,只有方法“a”与初始值完全匹配。因此,如果不变式是只有初始值代表初始化值,那么这是最准确的方法。当然,这些方法从一开始就没有对保护不变量起到任何作用,这在我看来更重要:不变量是否或可以有效执行。
OGREnvelope虽然这并不是一个代码审查网站,但就github 上的类(似乎只是 AABB)的链接代码编辑而言,我认为应该注意以下几点:
IsInit基于其代码 - 似乎意味着返回 AABB 是否实际上已由用户设置。不在于它是否处于其初始状态/价值,正如可以IsInit论证的那样(并误导了我相信)。IsValid就我个人而言,我更喜欢这个测试的名称。MinX值永远不应该大于 ,MaxX也不MinY应该大于MaxY。换句话说,在有效的 AABB 中,它们永远不应该被逆转。MinX应始终小于或等于MaxX(最小和最大 Y 变量相同)。max()和lowest()值更广泛的有效 AABB。MinX, 、MaxX、MinY、MaxY成员变量是可公开访问的,这意味着IsInit不变量本身只是建议性的,因为没有封装来保护不变量。在更广泛的背景下,NaN 是不合适的。不变量从来都不是真的MinX != std::numeric_limits<double>::infinity()。并且IsInit(如该代码中实现的)充其量是不完整的。在将其重命名为类似的上下文中IsValid,逻辑上更一致的实现是:
bool IsValid() const
{
return !std::isnan(MinX) && !std::isnan(MinY) && MinX <= MaxX && MinY <= MaxY;
}
Run Code Online (Sandbox Code Playgroud)
通过此实现,有效的 AABB 是一个OGREnvelope其值都是有效数字(没有一个是 NaN)且其最小值必须分别小于或等于 X 和 Y 的最大值的 AABB。