2013-02-22 3 views
0

Pourquoi ce code imprimé 2,4099999999999997, au lieu de seulement 2,41Java opérateur du module

public class Main 
{ 
    public static void main(String args[]) 
    { 
     double d = 5.55%3.14; 
     System.out.println(d); 
    } 
} 
+5

[Ce que tout scientifique devrait savoir sur l'arithmétique en virgule flottante ] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). – Pshemo

+2

pourquoi êtes-vous tous downvoting ceci, vous avez besoin d'une compréhension profonde de arithmétique à virgule flottante pour comprendre cela .. – cIph3r

+3

Il n'y a rien de très profond dans "float/double représente les nombres réels dans quelques octets et ils doivent faire des approximations pour le faire. ". C'est l'informatique de base. –

Répondre

1

Java double peut avoir des problèmes de précision.

Pourquoi n'essayez-vous pas BigDecimal?

+8

"Problèmes de précision" donne l'impression d'être un bug; ce n'est pas un problème, c'est un point flottant. – LittleBobbyTables

+0

Et BigDecimal ne résout pas cela: 'import java.math.BigDecimal; public class Main { \t public static void principal (String [] args) { \t \t final BigDecimal d = new BigDecimal (5.55); Final BigDecimal APPROXPI = new BigDecimal (3.14); \t \t System.out.println (à partir de (APPROXPI)); \t \t //2.409999999999999698019337301957421004772186279296875 \t}} ' – cIph3r

+1

@ cIph3r effectivement BigDecimal résout, mais nous avons besoin d'utiliser la représentation chaîne de nombres dans les arguments du constructeur comme' BigDecimal ("5,55") 'et' BigDecimal ("3,14") ' pour obtenir des valeurs précises. Jetez un coup d'œil à [cette explication] (http://www.youtube.com/watch?feature=player_detailpage&v=wbp-3BJWsU8#t=373s). – Pshemo

2
import java.text.DecimalFormat; 

double d = 5.55%3.14;  
DecimalFormat df = new DecimalFormat("#.##"); 
System.out.println(df.format(d)); 

Ajouter DecimalFormat

Edit:

Vous pouvez également

double d = 5.55%3.14; 
    System.out.printf("%1$.2f", d); 
+1

bien, en fait cela ne résout pas vraiment le problème, la formatter décimale complète juste l'inexactitude loin ... ' DecimalFormat df = new DecimalFormat ("##. ##. ###################"); ' va vous montrer .. – cIph3r

+0

Pour être juste, dans de nombreuses circonstances, c'est une solution complètement acceptable. – Medo42

3

Le problème n'est pas l'opérateur modulo, mais plutôt la nature des nombres à virgule flottante. Un double ne peut pas contenir la valeur précise de 5.55, 3.14 ou 2.41, de sorte que vous obtenez une réponse approximative.

Pour mieux comprendre cela, essayez d'écrire la valeur 1/3 sous forme décimale, lorsque vous avez seulement un espace limité sur le papier pour l'écrire. Vous finirez avec quelque chose comme 0.33333, qui est une approximation de la valeur réelle. La même chose arrive à 5.55 lorsque vous l'écrivez en binaire - il se transforme en 101.10001100110011001100110011... qui est coupé quelque part pour s'adapter à l'espace du double.

1

la raison en est que Java ne fait pas les mathématiques comme nous le faisons. java utilise des nombres binaires (du chapitre 4 du gros livre java de Horstmann) donc à un ordinateur, 435 = 4 * 10^2 + 3 * 10^1 + 5 * 10^0

il le fait parce que les nombres binaires (1 ou 0) sont plus faciles à manipuler puisque les commutateurs de l'ordinateur sont allumés ou éteints (1 ou 0).

Ceci provoque des arrondis occasionnels. Si vous voulez forcer à arrondir, faites des choses comme utiliser un format décimal, ou si vous avez juste besoin de la valeur affichée arrondie, vous pouvez utiliser String.format ou printf