我目前有一些代码,我必须规范化双精度矢量(将每个元素除以总和)。在调试时,我有时会看到向量中的元素都是0.0。如果我然后得到元素的总和,我得到0.0或4.322644347104e-314 #DEN(我最近发现的是非规范化数字)。当sum为0.0或非规格化数时,我想阻止对情形进行归一化。我能想到处理这两种情况的唯一方法是检查总和是否小于'epsilon',其中epsilon是一个小数字(但我不确定制作epsilon有多小)。
我有两个问题:
答案 0 :(得分:9)
#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)
,则会出现下溢。答案 1 :(得分:8)
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) {
// ...
}
答案 2 :(得分:0)
您可以在获取总和时使用标记,以确保不是每个元素都等于0.