IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

division par 0 c#


Sujet :

C#

  1. #1
    Membre chevronné
    Inscrit en
    Octobre 2005
    Messages
    400
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 400
    Par défaut division par 0 c#
    bonjour,

    aujourd'hui j'ai remarqué un truc bizarre en C# :

    On peut effectuer des divisions par zéro sur des doubles


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double a = 1.0;
    double b = 0.0;
     
    double c = a/b;
    ca ne plante pas, ça retourne "+Infinity"
    Quelqu'un saurait-il pourquoi, et dans quel cas c'est utile ?

  2. #2
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Ben c'est vrai ce qu'il te dit, enfin ... pas d'un point de vue mathématique de la vie courrante, mais ça tient la route :
    "10 / 0 = oo" ... ou plutot 1 / n tend vers oo quand n tend vers 0

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Salut,

    c'est "normé" comme ca :

    12.1.3 Handling of floating-point data types
    [...]

    The standard defines special values, NaN, (not a number), +infinity, and –infinity. These values are returned on overflow conditions. A general principle is that operations that have a value in the limit return an appropriate infinity while those that have no limiting value return NaN (see the standard for details).

    [Note: The following examples show the most commonly encountered cases.]
    X rem 0 = NaN

    0 * +infinity = 0 * -infinity = NaN

    (X / 0) = +infinity, if X > 0
    NaN, if X = 0
    infinity, if X < 0

    NaN op X = X op NaN = NaN for all operations

    (+infinity) + (+infinity) = (+infinity)

    X / (+infinity) = 0

    X mod (-infinity) = -X

    (+infinity) - (+infinity) = NaN

    [...]
    3.31 Div

    Integral operations throw DivideByZeroException if value2 is zero.
    Floating-point operations never throw an exception (they produce NaNs or infinities instead).
    Ca n'explique pas le pourquoi ca a été normé comme ca, mais explique au moins le comportement. =)

  4. #4
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    ce probleme m'etonne aussi et il semblerait que ce soit présent dans les autres languages aussi
    http://forum.java.sun.com/thread.jsp...sageID=3821046

    une divison par un double renvoie Infinity

    but why????

  5. #5
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Je vois pas ce qui vous surprend. Mathématiquement, c'est correct : un réel positif divisé par un epsilon positif tendant vers zéro, ça tend vers + l'infini. et comme +Infinity et -Infinity sont des doubles valables, autant s'en servir.

    EDIT : smyley l'avait déjà écrit, en plus

  6. #6
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    C'est probablement parce qu'au niveau du processeur même, les entier et les "flottants" ne sont pas gérés de la même façon : diviser un entier et diviser un réel ne se fait pas de la même facon. Enfin c'est les souvenirs que j'en avais à l'époque ou les flottants étaient manipulés par les co-processeurs et pas par le processeur (ça existe encore les co-processeurs arithmétique ?).

    Ah, la bonne époque ou on investissait dans un co-processeur pour venir aider le processeur, ainsi qu'une carte 3D pour aider la carte 2D...

  7. #7
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    Citation Envoyé par Guulh Voir le message
    un epsilon positif tendant vers zéro
    Sauf que 0.0 n'est pas un epsilon positif tendant vers zéro, mais précisément 0.0

  8. #8
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    divisé par un epsilon positif tendant vers zéro
    et pourquoi (je suis nul en maths ^^) 0.0 ne pourrait pas être un beau 0, plutot que tendant vers 0?
    le 0 n'existe pas chez les flottants? Il n'existe pas de moyen de le représenter?

  9. #9
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    Tout ce qui est en dessus me parait correct !

    Cependant j ai une question : pourquoi je ne peut pas catcher la division avec DivideByZeroException ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    double a = 1.0;
    double b = 0.0;
    double c;
     
    try
    {
        c = a / b;                
    }
    catch( DivideByZeroException e)
    {
       //on passe jamais ici               
    }

  10. #10
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Parce que cette exception n'est pas levée. La division par un double égal à zéro est une opération licite qui renvoie un double bien défini (à savoir +Infinity ou -Infinity).

  11. #11
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Comme dit supra, la division par 0 de double ne génère pas d'exception, contrairement à la division par 0 d'un entier.

  12. #12
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 707
    Par défaut
    En effet la majorité des langages de programation se refèrent à la norme IEEE 754 etant donné que c'est ce qui est pris en charge par la majorité des (co)processeurs actuels. Cette norme définit de manière assez précise le comportement des nombres à virgule flotante sur les opérations standards.

    Il me parrait assez logique que la division par 0 retourne soit +oo soit -oo vu que les nombres flottants ne sont pas des valeurs formelles.
    Seule la division de 0 par 0 posse problème, mais elle ne génèrera pas non plus d'exception. Elle retournera la valeur NaN(not a number) comme prévu dans la spécification IEEE 754.

  13. #13
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Mais c'est bizarre que celà suprenne les gens, pourquoi un réel divisé par 0 ne donnerai pas l'infini ? Pourtant en terminale on fait ça en math et ça donne les même résultats avec notamment les formes indéterminées et tout et tout ...
    Et si l'on a besoin d'obtenir un DividedByZeroException, il vaudrait mieux faire soit même la vérification avant de diviser, ou même, regarder le resultat de la division pour vérifier qu'il s'agit toujours d'un nombre ( l'infini n'ettant pas un nombre .. )

  14. #14
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par smyley Voir le message
    Et si l'on a besoin d'obtenir un DividedByZeroException,
    Le DividedByZeroException est une erreur de "bas niveau" envoyée par le processeur sur les divisions de nombres entiers (il n'existe rien permettant de dire "infini" pour un entier dans le stockage natif. Le stockage des réels lui n'a rien de natif).

  15. #15
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Le DividedByZeroException est une erreur de "bas niveau" envoyée par le processeur sur les divisions de nombres entiers (il n'existe rien permettant de dire "infini" pour un entier dans le stockage natif. Le stockage des réels lui n'a rien de natif).
    Justement, comme on peut pas l'avoir de toute façon, il faut faire soit même les test pour ne pas se retrouver avec des NaN ou des infini se balladant dans le programme ...

  16. #16
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par smyley Voir le message
    Justement, comme on peut pas l'avoir de toute façon, il faut faire soit même les test pour ne pas se retrouver avec des NaN ou des infini se balladant dans le programme ...
    Je ne serais pas aussi catégorique : un infini se "baladant" (j'aime bien cette expression) dans un programme *peut* avoir un sens, tout dépend de ce qu'on manipule (une division par 0 n'en ayant pas en général, je suis d'accord).

  17. #17
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Le stockage des réels lui n'a rien de natif).
    Les processeurs actuels ne gèrent pas les réels nativement ? Je suis un peu étonné là... Car de mémoire à l'époque des co-processeurs donc je parlais un peu plus haut, eux le faisaient.

  18. #18
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Nikoui Voir le message
    Les processeurs actuels ne gèrent pas les réels nativement ? Je suis un peu étonné là... Car de mémoire à l'époque des co-processeurs donc je parlais un peu plus haut, eux le faisaient.
    Tout à fait, les "87" (intégrés au CPU principal à partir du 486, si ma mémoire n'est pas encore trop atteinte).

    Mais, quoiqu'il soit possible que je me trompe, les "+/-Infinite" et NaN ne sont pas intégré dans ce stockage natif, non ?

  19. #19
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 707
    Par défaut
    Citation Envoyé par smyley Voir le message
    Mais c'est bizarre que celà suprenne les gens, pourquoi un réel divisé par 0 ne donnerai pas l'infini ? Pourtant en terminale on fait ça en math et ça donne les même résultats avec notamment les formes indéterminées et tout et tout ...
    Et si l'on a besoin d'obtenir un DividedByZeroException, il vaudrait mieux faire soit même la vérification avant de diviser, ou même, regarder le resultat de la division pour vérifier qu'il s'agit toujours d'un nombre ( l'infini n'ettant pas un nombre .. )
    Ca peut surprendre des gens car:
    - Pour les entiers on a une exception et que on pourrait s'attendre à ce qu'il en soit de même pour les flottants
    - En math on m'a appris que -1/0 = -oo n'est pas correct. Cependant il et vrai que la limite de -1/x quand x tend vers 0 vaut -oo
    - On imagine pas forcément si on ne s'est pas correctement documenté sur le sujet que la norme des flottants permet de représenter les valeur infinies et NaN alors que ce n'est pas le cas des entiers.

    Le DividedByZeroException est une erreur de "bas niveau" envoyée par le processeur sur les divisions de nombres entiers (il n'existe rien permettant de dire "infini" pour un entier dans le stockage natif. Le stockage des réels lui n'a rien de natif).
    Je ne sais pas trop ce que tu appelles natif mais la plupart des (co)processeurs modernes fournissent des instructions natives pour traiter les flottants.

    Justement, comme on peut pas l'avoir de toute façon, il faut faire soit même les test pour ne pas se retrouver avec des NaN ou des infini se balladant dans le programme ...
    Parfois l'infini ou NaN peut avoir un sens particulier qui t'interesse, si ce n'est pas le cas, tu dois le traiter.
    La différence est que au lieu de traiter l'exception tu testes si tu as l'infini ou NaN.

    Ca n'a rien de complexe il suffit juste d'être conscient que les flottants et les entiers ne fonctionnent pas de la même manière car ils utilisent 2 normes différentes.

  20. #20
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 707
    Par défaut
    Mais, quoiqu'il soit possible que je me trompe, les "+/-Infinite" et NaN ne sont pas intégré dans ce stockage natif, non ?
    Il sont totalement integrés à la norme et ont une représentation selon celle ci:
    extrait de wikipédia:
    si l'exposant est égal à 2e − 1, et si la mantisse est nulle, le nombre est ±infini (selon le bit de signe)
    si l'exposant est égal à 2e − 1, mais que la mantisse n'est pas nulle, le nombre est NaN (not a number : pas un nombre).
    On peut donc les stoquer et effectuer toutes les opération sur ceux ci.

    La plupart des opérations sur ces nombres sont également définies par la norme. Par exemple il faut savoir que NaN == NaN retournera faux, ce qui peut être assez déroutant!

Discussions similaires

  1. Comment faire une division par 5 avec les decalages
    Par Zaion dans le forum Assembleur
    Réponses: 7
    Dernier message: 05/11/2004, 18h33
  2. [CR8.5] Problème de division par zéro sur formule
    Par franck.cvitrans dans le forum Formules
    Réponses: 3
    Dernier message: 10/06/2004, 14h41
  3. Division par 16 en C
    Par hermannd dans le forum C
    Réponses: 18
    Dernier message: 13/02/2004, 15h10
  4. [LG]a divise par b
    Par backsync dans le forum Langage
    Réponses: 8
    Dernier message: 22/10/2003, 22h37
  5. probleme avec une division par zéro
    Par jcharleszoxi dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/03/2003, 19h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo