web-dev-qa-db-fra.com

Combien de chiffres significatifs ont des flottants et des doubles en java?

Un float a-t-il 32 chiffres binaires et un double 64 bits? La documentation était trop difficile à comprendre.

Tous les bits sont-ils traduits en chiffres significatifs? Ou l'emplacement de la virgule prend-il quelques bits?

73
Eamon Moloney

float : 32 bits (4 octets) où 23 bits sont utilisés pour la mantisse (environ 7 chiffres décimaux). 8 bits sont utilisés pour l'exposant, ainsi un nombre à virgule flottante peut "déplacer" le point décimal à droite ou à gauche à l'aide de ces 8 bits. Cela évite de stocker beaucoup de zéros dans la mantisse, comme dans 0.0000003 (3 × 10-sept) ou 3000000 (3 × 10sept) Il y a 1 bit utilisé comme bit de signe.

double : 64 bits (8 octets) où 52 bits sont utilisés pour la mantisse (environ 16 chiffres décimaux). 11 bits sont utilisés pour l'exposant et 1 bit est le bit de signe.

Puisque nous utilisons binaire (seulement 0 et 1), un bit dans la mantisse est implicitement égal à 1 (les deux utilisent cette astuce, à la fois float et double) lorsque le nombre est différent de zéro.

De plus, comme tout est en binaire (mantisse et exposants), les conversions en nombres décimaux ne sont généralement pas exactes. Des nombres comme 0,5, 0,25, 0,75, 0,125 sont stockés exactement, mais 0,1 ne l’est pas. Comme d'autres l'ont déjà dit, si vous devez stocker des centimes avec précision, n'utilisez pas float ou double, utilisez int, long, BigInteger ou BigDecimal.

Sources:

http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

http://en.wikipedia.org/wiki/Binary64

http://en.wikipedia.org/wiki/Binary32

94
marcus

Un float de 32 bits a environ 7 chiffres de précision et un double de 64 bits a environ 16 chiffres de précision

Longue réponse:

Les nombres à virgule flottante ont trois composantes:

  1. Un bit de signe, pour déterminer si le nombre est positif ou négatif.
  2. Un exposant, pour déterminer la magnitude du nombre.
  3. Une fraction, qui détermine la distance entre deux valeurs d'exposant. Ceci est parfois appelé “le significande, la mantisse ou le coefficient”

Essentiellement, cela revient à sign * 2^exponent * (1 + fraction). La "taille" du nombre, son exposant, ne nous concerne pas, car elle ne fait que mettre à l’échelle la valeur de la fraction. Sachant que log₁₀(n) donne le nombre de chiffres de n, †, nous pouvons déterminer la précision d'un nombre à virgule flottante avec log₁₀(largest_possible_fraction). Parce que chaque bit dans un float stocke 2 possibilités, un nombre binaire de n bits peut stocker un nombre allant jusqu'à 2ⁿ - 1 (Un total de 2ⁿ valeurs où l’une des valeurs est zéro). Cela devient un peu plus poilu, car il s'avère que les nombres à virgule flottante sont stockés avec un bit de fraction de moins qu'ils ne peuvent utiliser, car les zéros sont représentés spécialement et tous les nombres non nuls ont au moins un bit binaire non nul. ‡

En combinant cela, les chiffres de précision pour un nombre à virgule flottante sont log₁₀(2ⁿ), où n représente le nombre de bits de la fraction du nombre à virgule flottante. Un nombre flottant de 32 bits a 24 bits de fraction pour environ 7,22 décimales de précision, et un double de 64 bits a 53 bits de fraction pour environ 15,95 décimales de précision.

Pour en savoir plus sur la précision en virgule flottante, consultez le concept de machine epsilon .


† Pour n ≥ 1 Au moins - pour les autres nombres, votre formule ressemblera davantage à ⌊log₁₀(|n|)⌋ + 1.

‡ “Cette règle est appelée de manière différente la convention des bits principaux, la convention des bits implicite ou la convention des bits cachés.” ( Wikipedia )

23
9999years

De spécification Java :

Les types à virgule flottante sont float et double et sont associés de manière conceptuelle aux valeurs et opérations IEEE 754 au format 32 bits simple précision et 64 bits, conformément à la norme IEEE pour l'arithmétique binaire en virgule flottante, ANSI/IEEE. Norme 754-1985 (IEEE, New York).

Comme il est difficile de faire quoi que ce soit avec des chiffres sans comprendre les bases de IEEE754, voici n autre lien .

Il est important de comprendre que la précision n'est pas uniforme et qu'il ne s'agit pas d'un stockage exact des nombres, comme c'est le cas pour les entiers.

Un exemple :

double a = 0.3 - 0.1;
System.out.println(a);          

empreintes

0.19999999999999998

Si vous avez besoin d'une précision arbitraire (par exemple à des fins financières), vous aurez peut-être besoin de Décimale grosse .

17
Denys Séguret

Une réponse mathématique normale.

Comprenant qu'un nombre à virgule flottante est implémenté sous la forme de bits représentant l'exposant et le reste, la plupart des chiffres (dans le système binaire), on se trouve dans la situation suivante:

Avec un exposant élevé, par exemple 10²³, si le bit le moins significatif est modifié, une différence importante entre deux nombres distinctement lisibles adjacents apparaît. De plus, le point décimal de base 2 fait que beaucoup de nombres de base 10 ne peuvent être qu'approximés; 1/5, 1/10 étant des nombres sans fin.

Donc, en général : les nombres en virgule flottante ne doivent pas être utilisés si vous vous souciez des chiffres significatifs. Pour les montants avec calcul, e, a, meilleure utilisation BigDecimal.

Pour la physique la virgule flottante les doubles sont adéquats, les flotteurs presque jamais. De plus, la partie en virgule flottante des processeurs, la FPU, peut même utiliser un peu plus de précission en interne.

7
Joop Eggen

Les nombres à virgule flottante sont codés en utilisant une forme exponentielle, c'est-à-dire quelque chose comme m * b ^ e, c’est-à-dire pas du tout comme des nombres entiers. La question que vous posez aurait un sens dans le contexte de nombres à point fixe . Il existe de nombreuses bibliothèques arithmétiques en points fixes disponibles.

En ce qui concerne l'arithmétique en virgule flottante: Le nombre de chiffres décimaux dépend de la présentation et du système de numération. Par exemple, il existe des nombres périodiques (0.33333) qui n’ont pas une présentation finie en décimal mais en ont une en binaire et vice versa.

Il convient également de mentionner que les nombres en virgule flottante jusqu’à un certain point ont une différence supérieure à un, c’est-à-dire value + 1 donne value, puisque value + 1 ne peut pas être encodé avec m * b ^ e, où m, b et e sont de longueur fixe. Il en va de même pour les valeurs inférieures à 1, c'est-à-dire que tous les points de code possibles n'ont pas la même distance.

De ce fait, il n’existe pas de précision exacte de n chiffres comme pour les nombres à virgule fixe, car tous les nombres comportant n chiffres décimaux ne possèdent pas de codage IEEE.

Il y a un document presque obligatoire que vous devriez lire à ce moment-là et qui explique les nombres en virgule flottante: Ce que tout informaticien devrait savoir sur l'arithmétique en virgule flottante .

3
scravy

Regarder Float.intBitsToFloat et Double.longBitsToDouble , ce qui explique en quelque sorte comment les bits correspondent aux nombres à virgule flottante. En particulier, les bits d'un float normal ressemblent à quelque chose comme

 s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW

où A ... W sont 23 bits - 0 et 1s - représentant une fraction en binaire - s vaut +/- 1, représenté par un 0 ou un 1 respectivement, et exp est un entier signé de 8 bits.

1
Louis Wasserman