检查c++中的零或非规范化数字
Check for zero or a denormalized number in c++
我目前有一些代码,我必须标准化一个双精度向量(除以每个元素的总和)。在调试时,我有时看到向量中的元素都是0.0。如果我然后取元素的和,我得到0.0或4.322644347104e-314#DEN(我最近发现这是一个非规范化的数字)。我希望防止在和为0.0或非规范化数字的情况下对向量进行规范化。我能想到的处理这两种情况的唯一方法是检查和是否小于'epsilon',其中epsilon是一个小数字(但我不确定如何使epsilon小)。
我有两个问题:- 考虑这些情况的最好方法是什么?
- 非规格化数的值是否依赖于机器?
C99提供fpclassify
检测非规范化数。它还提供c++ 0x和Boost.Math.
// C++0x
#include <cmath>
using std::fpclassify;
// Boost
//#include <boost/math/special_functions/fpclassify.hpp>
//using boost::math::fpclassify;
if(fpclassify(sum) == FP_SUBNORMAL) {
// ...
}
#include <limits>
#include <cmath>
double epsilon = std::numeric_limits<double>::min();
if (std::abs(sum) < epsilon) {
// Don't divide by sum.
}
else {
// Scale vector components by sum.
}
附录
既然你在尝试标准化一个向量,我敢说你的和是向量元素的平方和,概念上
double sum = 0;
for (unsigned int ii = 0; ii < vector_size; ++ii) {
sum += vector[ii]*vector[ii];
}
sum = std::sqrt(sum);
以上有三个问题。
- 如果其中任何一个矢量分量的大小大于
sqrt(max_double)
,则得到无穷大。 - 如果其中任何一个矢量分量的量级小于
sqrt(min_double)
,则将得到底流。 - 即使这些数字表现良好(在2*10-154和10154之间),如果震级变化很大(106就可以了),上述问题也是有问题的。如果是这种情况,你需要一个更复杂的斜边函数。
可以在求和时使用标记,以确保不是每个元素都等于0。
相关文章:
- 如何确定我已使用非编码文件到达 EOF?
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将公共但非静态的成员函数与ALGLIB集成
- 提升精神:解析布尔表达式并简化为规范范式
- 不同翻译单元中不可重载的非内联函数定义
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 初始化具有非默认构造函数的std::数组项的更好方法
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- C++,术语,非规范,阻塞,检测消息结束
- 是C 标准非规范的核心语言规范中的注释和示例
- 局部变量作为非类型参数,具有模板规范
- 在C++中创建非规范化(亚正规)浮点值
- Objective-C中的非规范化浮点
- 是否存在允许将非const模板实参类型隐式转换为const的规范方法?
- 检查c++中的零或非规范化数字
- 如何在单位边界框中规范化3D非彩色网格
- 使用 C++,有没有办法检测浮点/双精度非正态化是否被编译器/系统"规范化"?
- c++规范是否允许非虚类的实例包含虚值表指针的内存?