Comment obtenir un résultat -0 dans les calculs en virgule flottante et le distinguer de +0 en C #?

StackOverflow https://stackoverflow.com/questions/1043816

  •  20-08-2019
  •  | 
  •  

Question

La documentation MSDN mentionne que le type double comprend un zéro négatif. Cependant, -1.0 / double.PositiveInfinity et -double.Epsilon / 2 semblent renvoyer un nombre normal de 0 (et se comparer à ce niveau). Comment puis-je obtenir -0?

Était-ce utile?

La solution

Voici un exemple pratique de différenciation entre les deux sans examiner les bits. Liens MSDN ici et ici m'a aidé à construire cet exemple.

static void Main(string[] args)
{
    float a = 5 / float.NegativeInfinity;
    float b = 5 / float.PositiveInfinity;
    float c = 1 / a;
    float d = 1 / b;
    Console.WriteLine(a);
    Console.WriteLine(b);
    Console.WriteLine(c);
    Console.WriteLine(d);
}

Sortie:

0
0
-Infinity
Infinity

Notez que -0 et 0 se ressemblent pour les comparaisons, les sorties, etc. Mais si vous divisez 1 par eux, vous obtenez -Infinity ou Infinity, selon le zéro que vous avez.

Autres conseils

Le zéro négatif a à voir avec la façon dont le nombre est stocké en binaire, pas avec un résultat réel pouvant être obtenu à partir d'un calcul mathématique.

Dans la mémoire en virgule flottante, le bit le plus haut est souvent utilisé pour indiquer le signe. Cela laisse 31 bits pour les données (dans une valeur à virgule flottante de 32 bits), il y a donc deux représentations pour zéro.

00000000 00000000 00000000 00000000

Ou
00000000 00000000 00000000 00000001

Les deux représentent zéro, mais un avec le bit de signe défini sur négatif.

Naturellement, cela se produirait normalement lorsque vous incrémenteriez le nombre positif le plus élevé possible, il déborderait à zéro.

Cependant, je pense que, par défaut, le type vérifie le dépassement de capacité et génère une exception au lieu de vous laisser déborder. Le seul moyen d'archiver réellement cette valeur consiste à le définir directement. En outre, -0 devrait toujours être égal à +0.

Vous en saurez plus sur Wikipeida

L’une des méthodes consiste à utiliser BitConverter.GetBytes. Si vous vérifiez les octets, vous verrez que le bit de signe de la valeur est effectivement défini, ce qui indique que son négatif est.

byte[] zeroBytes = BitConverter.GetBytes(zero);
byte[] negZeroBytes = BitConverter.GetBytes(negZero);

bool sameBytes = zeroBytes[7] == negZeroBytes[7];

Essayez ceci. Si pz est positif (zéro) et que nz est négatif (zéro):

Double.PositiveInfinity/pz => Double.PositiveInfinity
Double.PositiveInfinity/nz => Double.NegativeInfinity

Cela provient de la spécification ECMA C # .

Vous pouvez obtenir un zéro négatif en divisant tout nombre positif par un infini négatif:

10.0/Double.NegativeInfinity

Après vérification, je constate que -1.0 / double.PositiveInfinity renvoie le résultat -0. En effet, 1.0 / (-1.0 / double.PositiveInfinity) renvoie -infinity .

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