Question

Je suis tombé sur la définition de .NET de double.NaN dans le code suivant:

public const double NaN = (double)0.0 / (double)0.0;

Ceci est fait de la même dans PositiveInfinity et NegativeInfinity.

double.IsNaN (avec suppression de quelques #pragmas et les commentaires) est défini comme:

[Pure] 
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static bool IsNaN(double d) 
{
    if (d != d)
    { 
        return true; 
    }
    else 
    {
        return false;
    }
}

Ceci est très contre-intuitif pour moi.

Pourquoi est-NaN définie comme la division par zéro? Comment est 0.0 / 0.0 représenté « dans les coulisses »? Comment la division peut par 0 être possible double, et pourquoi NaN != NaN?

Était-ce utile?

La solution

réponse assez simple ici. NET Framework a mis en œuvre la norme à virgule flottante spécifiée par la norme IEEE (System.Double est conforme à la norme IEC 60559: 1989 ( IEEE 754) de série binaire arithmétique à virgule flottante.) . En effet, l'arithmétique en virgule flottante a fait travailler dans de nombreux systèmes, et non pas seulement x86 / 64 architectures, en suivant les conventions ce qui garantit qu'il y aura moins de problèmes de compatibilité (par exemple le code portage d'un DSP dans un processeur x86).

En ce qui concerne le d! = D, ceci est une optimisation des performances. Fondamentalement, cette instruction repose sur une instruction matérielle qui peut très rapidement déterminer si deux nombres à virgule flottante double sont égaux. En vertu de la norme, NAN! = NAN et est donc le meilleur moyen de test. Essayer de trouver une référence pour vous.

Autres conseils

  

Pourquoi est-NaN définie comme division par   zéro? Comment la division peut par 0 soit   possible en double, et pourquoi NaN   ! = NaN?

Tous ces sont mandatés par le IEEE 754 standard, ce qui à peu près tout le confort moderne mettre en œuvre des CPU.

  

Comment est 0,0 / 0,0 représentés « dans les coulisses »?

En ayant un exposant avec tous les bits mis à 1 et une mantisse d'au moins un bit mis à 1. On notera que cela signifie qu'il y a un grand nombre de différentes configurations de bits qui représentent tous NaN - mais, comme mentionné ci-dessus, même si les motifs de bits sont identiques, ils doivent être considérés comme différents (c.-à-faux == doit retourner).

De C # Spec:

  

14.9.2 opérateurs de comparaison à virgule flottante   Les opérateurs de comparaison en virgule flottante sont prédéfinies:

     
    

opérateur booléen == (x float, float y); opérateur booléen == (double x, double y);
    bool operator = (x float, float y!); bool operator = (double x, double y)!
    opérateur booléen <(x flotteur, le flotteur y); opérateur booléen <(double x, double y);
    opérateur booléen> (x float, float y); opérateur booléen> (double x, double y);
    opérateur booléen <= (x float, float y); opérateur booléen <= de (double x, double y);
    opérateur booléen> = (x float, float y); opérateur booléen> = (double x, double y);

  
     

Les opérateurs comparent les opérandes selon les règles de la norme IEC 60559:    Si l'un des opérandes est NaN, le résultat est faux pour tous les opérateurs, à l'exception! =, Dont le résultat est vrai. Pour tout deux opérandes, x! = Y produit toujours le même résultat que! (X = = y). Cependant, quand un ou les deux opérandes sont NaN, le <,>, <= et> = opérateurs ne produisent pas les mêmes résultats que la négation logique de l'opérateur inverse. [Exemple: Si l'un de x et y est NaN, alors x = Y) est vrai. Exemple d'extrémité]

En ce qui concerne la façon dont NaN est représenté dans les coulisses, le wikipedia article sur l'IEEE spec a quelques exemples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top