6
votes

Vérifiez zéro ou un nombre dénormalisé en C ++

J'ai actuellement du code où je dois normaliser un vecteur de doubles (diviser chaque élément par la somme). Lors du débogage, je vois parfois que les éléments du vecteur sont tous 0,0. Si je prends ensuite la somme des éléments, je reçois 0,0 ou 4.322644347104e-314 # Den (que j'ai récemment découvert était un nombre dénormalisé). Je voudrais empêcher la normalisation du vecteur des cas lorsque la somme est soit 0,0 ou un nombre dénormalisé. La seule façon dont je pouvais penser à la manipulation de ces deux cas consiste à vérifier si la somme est inférieure à 'epsilon', où Epsilon est un petit nombre (mais je ne suis pas sûr de la taille de l'Epsilon).

J'ai 2 questions:

  1. Quelle est la meilleure façon de prendre en compte ces cas?
  2. est la valeur de la machine de numéro de nombres dénormalisée dépendante?

5 commentaires

Je pensais que les moyens de normalisation ==> "diviser en moyenne de somme"


Des tonnes de choses que vous pouvez appeler "normaliser". Par exemple, vous voudrez peut-être diviser par la racine PTH de la somme des pouvoirs PTH des éléments ...


@iammilind: Normaliser signifie généralement «diviser par la racine carrée de la somme des carrés». Ou par une autre l p NORM.


@Kerrek: une norme LP serait en fait la racine PTH de la somme des pouvoirs PTH de les valeurs absolues des éléments. Sa seule la même chose pour même p. En particulier, si c'est le L₁, vous aurez besoin de la somme des valeurs absolues. Mais la norme la plus courante et les plus utile plus utile (car elle est invariante sous transformations orthogonales) est bien la L₂, où vous avez besoin de la racine carrée de la somme des carrés.


@Leftaroundounbout: Ouais, tu as raison bien sûr - je pense que je viens de dacty de taper paresseux :-) Je suppose que vous TOUJOURS Besoin de la valeur absolue si vous voulez permettre aux nombres complexes ...


3 Réponses :


10
votes
double sum = 0;
for (unsigned int ii = 0; ii < vector_size; ++ii) {
    sum += vector[ii]*vector[ii];
}
sum = std::sqrt(sum);

1 commentaires

De la formulation de l'OP, je pense que vous pouvez vouloir min () plutôt que denorm_min () .



-1
votes

Vous pouvez utiliser un drapeau pendant que vous prenez la somme pour vous assurer que tous les éléments ne sont pas égaux à 0.


0 commentaires

10
votes

C99 fournit FPClassify code> pour détecter le nombre dénormalisé. Il est également fourni avec C ++ 0x et 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) {
    // ...
}


0 commentaires