2010-09-08 5 views
6

Sur ma machine, et actuelle version .net Math.exp (-1000) retourne 0.0, comme cela est raisonnable parce est un nombre qui est trop faible pour représenter un double.Math.exp d'un grand nombre négatif

Puis-je compter sur cela pour rester sur d'autres machines, et à l'avenir builts .net? Msdn me dit Math.exp (Double.NegativeInfinity) renvoie 0.0 (que je m'attends donc à le rester à l'avenir), mais qu'en est-il de -1000?

Répondre

4

La fonction Math.Exp() est définie comme agissant sur les types de double précision. Notez que exp (-1000) == 5.08e-435, bien en dessous de la plus petite valeur absolue qui peut être exprimée en double.

Je pense qu'il est sûr de dire que tout environnement où les nombres à virgule flottante IEEE sont utilisés, exp(-1000) sera 0.0. Il est très peu probable que .Net quittera jamais le point flottant IEEE. En termes plus généraux, je suppose que vous vous intéressez à la question de savoir si les petites quantités peuvent être arrondies à zéro. Bref, oui, à l'IEEE.

Cependant, il est probablement préférable de ne pas concevoir ce comportement dans votre code. Comme le suggère Darin, comparez les valeurs à virgule flottante dans une tolérance. Si vous avez une raison de travailler avec des nombres très petits ou grands, envisagez de suivre la quantité comme un logarithme et d'effectuer des opérations dans le domaine logarithmique (si vous avez besoin de multiplier, ajoutez les logarithmes, etc.). Vous pouvez utiliser une bibliothèque mathématique de haute précision, mais même avec des nombres qui deviennent très petits, le calcul peut être sujet à de grandes erreurs d'arrondi et à une faible stabilité numérique.

Enfin, si votre intention est de calculer 1.0 - Math.Exp(-num) ou Math.Exp(-num) - 1, recherchez une fonction de bibliothèque qui calcule directement ces derniers pour obtenir la meilleure précision.

2

Non, on ne peut jamais se fient qu'une variable de type double est exactement égale à quelque chose. N'écrivez jamais quelque chose comme ça. Ne jamais utiliser l'opérateur == pour comparer deux doubles opérandes:

double d = ... 
if (d == 0.0) { 

} 

Au lieu de cela, vous devez définir une précision désirée et toujours travailler avec cette précision:

double epsilon = 1e-5; 
double d = ... 
if (Math.Abs(d - 0.0) < epsilon) { 

} 
+0

Quelle est la raison du downvote? S'il vous plaît laissez un commentaire lors de la downvotation. –

1

Utilisez le haut-construction qu'ils ont déclaré.

Il devrait conserver en l'état en raison des limitations de taille en ce qui concerne un double, mais je préférerais l'utilisation de la constante intégrée à la classe et confirmée par MSDN.

+0

Que voulez-vous dire exactement par la construction intégrée? – willem

+0

@Willem - Je me suis référé à l'utilisation de 'Double.NegativeInfinity', au lieu d'un nombre magique si possible pour les opérations de limite. –

1

Non, ce n'est jamais une bonne idée de rappeler une telle exception. Ce n'est pas une exception levée, mais le fait qu'il soit trop petit pour afficher et que 0.0 vous donne une exception n'en est pas moins une exception. Il est préférable de rester avec des constantes pour quelque chose comme ça.

+0

Citer la source? Je ne vois aucune raison de croire qu'il y a une exception. – recursive

+0

pas une exception dans le sens traditionnel, mais plus le fait que le type de variable ne peut pas gérer le nombre de sorte qu'il donne la valeur par défaut de 0.0 Après tout, une exception n'est rien de plus que votre code ne peut pas gérer. – Adkins

Questions connexes