Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

[.NET 2] Math.Pow est buggé !

Introduction

Imaginons que vous souhaitiez obtenir la racine cubique de -0.5.

Vous écrivez dès lors le code suivant : -0.5 ^ (1/3) ou Math.Pow(-0.5, 1/3)

Quelle n'est pas votre suprise d'apprendre que cela fait... NaN ! Pas très pratique quand on sait que cette racine existe pourtant bel et bien !

Pourquoi ce bug ?

En fait, quand vous avez un exposant inférieur à 1, Math.Pow utilise une formule contenant le logarithme. Or le logarithme n'est défini que pour les nombres positifs. Conclusion, pour les nombres négatifs, point de racine cubique.

Comment corriger ce bug ?

Il faut dès lors ruser... Voici ma solution (VB), qui consiste en fonction "v(n, x)"

Public Module MathModule
    Public Function v(ByVal c As Double, ByVal x As Double) As Double
        If x < 0 Then 'Si le nombre est négatif
            v = -((-x) ^ (1 / c)) 'Chercher la racine du nombre positif
            If Math.Round(v ^ c, 3) <> Math.Round(x, 3) Then 
                v = Double.NaN 'Et renvoyer NaN si cette racine ne s'applique pas
            End If
        Else
            v = x ^ (1 / c)
        End If
    End Function
    Public Function v(ByVal x As Double) As Double
        v = x ^ (0.5)
    End Function
End Module
Publié samedi 10 novembre 2007 21:10 par FREMYCOMPANY
Classé sous : , ,
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

# re: [.NET 2] Math.Pow est buggé !

samedi 10 novembre 2007 21:57 by brunews

Que ce ne soit pas pratique OK mais dire que c'est buggé quand la règle du jeu est respectée...

Math.Pow(x, y)

Si x &lt; 0 mais pas Moins l'infini:

Valeur de retour = Nan

DIXIT MSDN.

# re: [.NET 2] Math.Pow est buggé !

samedi 10 novembre 2007 23:17 by Matou

Selon moi, il s'agit plutôt d'un bug documenté (un peu comme la gestion de certaines dates en OpenXML).

# re: [.NET 2] Math.Pow est buggé !

dimanche 11 novembre 2007 08:43 by smo

Ce n'est pas "buggé", c'est clairement codé comme cela. Cf ici:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94376

et je crois que c'est compatible avec l'API équivalente Java (mais je ne suis pas sûr ;-)

# re: [.NET 2] Math.Pow est buggé !

dimanche 11 novembre 2007 13:08 by FREMYCOMPANY

Oui, je suis d'accord avec toi Matou, pour moi ce n'est rien de plus qu'un "bug" documenté.

Si une fonctione matématique ne renvoie pas la réponse qu'elle est censée fournir, c'est qu'elle est buggée. Que ce soit expliqué dans la MSDN ou pas...

Si la fonction 5-(-5) renvoyait 0, mais que la documentation prévient que la soustraction de nombres de signe opposée renvoie leur addition, vous n'allez pas dire "que ce n'est pas un bug"...

Surtout que

Dim E as Double = -1.1

E ^ (1/3) = -1.1 ^ (1/3) renvoie False... car -1.1 ^ (1/3) est précompilé et renvoie bien la bonne réponse (-1.331).

# re: [.NET 2] Math.Pow est buggé !

dimanche 11 novembre 2007 13:36 by RaptorXP

Rien à voir avec un bug, ni même un bug by design. NaN est la bonne réponse (mathématiquement parlant).

Quand tu calcules 1/3, le résultat en mémoire n'est pas égal à 1/3, c'est normal puisqu'il y a une infinité de 3.

Du coup le résultat de pow n'est pas réel, donc NaN est bien la bonne réponse.

Si tu calcules (-1)^2.00001 tu auras le même problème.

Pour éviter ça tu n'as qu'a toujours calculer la puissance d'un nombre positif (et ajuster le signe à la main).

Morale de l'histoire : renseigne toi avant de crier au loup.

# re: [.NET 2] Math.Pow est buggé !

dimanche 11 novembre 2007 20:52 by FREMYCOMPANY

Ce que tu dis est faux car si je tape -1.1^(1/3) directement dans le code, j'obtiens bien le résultat attendu ! Et si je fais Pow(1.1, 0.3333333333333331), aussi.

Donc ton argument ne tiens pas

# re: [.NET 2] Math.Pow est buggé !

lundi 12 novembre 2007 15:44 by RaptorXP

Ce n'est pas un "argument", c'est ce qu'on apprend en math.

Si tu ne me crois pas regarde sur Wikipedia :

http://fr.wikipedia.org/wiki/Puissance_(math%C3%A9matiques_%C3%A9l%C3%A9mentaires)

"(Les puissances entières sont en fait des cas particuliers de) la fonction exponentielle :

a^b = exp(b*ln a) définie par tout réel a STRICTEMENT POSITIF"

Si tu veux étendre la définition à a négatif, tu fais appel aux racines n-ièmes de l'unité qui ne sont définies que pour n entier. Donc les seules puissance auxquelles tu *pourrait* étendre cette fonction pour a négatif (mais ce n'est pas la définition d'exponentielle), c'est pour b entier positif et b = (1/3), (1/5)... sinon il n'y a pas de racine réelle pour 0.3, ou 2.1.

Pour tes exemples :

- si tu tapes -1.1^(1/3) ça marche... ben oui, mais si tu tapes (-1.1)^(1/3), en faisant attention a la priorité des opérateur, tu obtiens bien NaN

- si tu fait Pow(1.1, 0.3333333333333331), évidemment que ça marche, le nombre que tu élève est positif.

Non, Math.Pow n'est pas buggée, rassure toi.

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- TechDays Paris 2010 : Déploiement de nouvelles technologies – Retour d’expérience par l’informatique de Microsoft par Blog Technique de Romelard Fabrice le il y a 1 heure et 8 minutes

- TechDays Paris 2010 : Plan de migration vers SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 4 heures et 51 minutes

- TechDays Paris 2010 : La pleinière du second jour par Blog Technique de Romelard Fabrice le il y a 5 heures et 56 minutes

- Visual Studio 2010 and .NET Framework 4 Release Candidate now available par Matthieu MEZIL le il y a 9 heures et 2 minutes

- Création d’une base de donnée sous SQL Azure par Le Blog (Vert) d'Arnaud JUND le il y a 9 heures et 58 minutes

- TechDays Paris 2010 : Les Services d’applications dans SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 19 heures et 58 minutes

- TechDays Paris 2010 : La GED et SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 23 heures et 56 minutes

- TechDays Paris 2010 : SharePoint 2010 et Les réseaux sociaux par Blog Technique de Romelard Fabrice le 02-08-2010, 15:40

- TechDays Paris 2010 : SharePoint 2010 – Description et nouveautés par Blog Technique de Romelard Fabrice le 02-08-2010, 14:33

- TechDays Paris 2010 : Pleinière Lundi par Blog Technique de Romelard Fabrice le 02-08-2010, 14:30