2012-06-26 6 views
-1

J'utilise le code suivant pour remplir un Spinner dans un de mes activités ...conversion étrange double à chaîne

for(double i = 0; i < 10 ; i+=0.1) { 
     rVoltsList.add(Double.toString(i)); 
    } 
    Spinner rVoltsSpinner = (Spinner) findViewById(R.id.recloseVoltsSpinner); 
    ArrayAdapter<String> rVoltsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, rVoltsList); 
    rVoltsSpinner.setAdapter(rVoltsAdapter); 

je suppose que cela me donnerait une liste comme suit: 0,0, 0,1 , 0,2, 0,3, 0,4 et ainsi de suite. Cependant, c'est ce que la liste ressemble quand je lance mon programme:

0.0 
0.1 
0.2 
0.30000000000000000000000004 
0.4 
0.5 
0.6 
0.7 
0.79999999999999999999 
0.89999999999999999999 
0.99999999999999999999 
1.09999999999999999999 
1.2 
1.3 
and this goes on until 9.99999999999999999998 

des idées?

+0

double possible de [Déplacement décimales sur dans un double] (http://stackoverflow.com/questions/4937402/moving-decimal-places-over-in-a -double) – assylias

Répondre

5

Utilisez ceci:

rVoltsList.add(String.format("%.1f", i)); 

Le problème est que ne sera pas rond. Les valeurs étranges sont dues au fait que 0.1 (base 10) n'a pas de représentation exacte en tant que double en Java, donc chaque fois que vous l'ajoutez à la variable de boucle, vous ajoutez quelque chose d'un peu différent de ce que vous pensez (si vous pardonnerez le jeu de mots).

Le même problème d'arrondi suggère que vous ne devriez pas utiliser un double comme variable de boucle. Il est très improbable que vous atteigniez exactement votre limite de boucle. Je réécrire votre boucle comme suit:

for(int i = 0; i < 100 ; ++i) { 
    rVoltsList.add(String.format("%.1f", i/10.0)); 
} 
+0

Cela fonctionne, mais je ne comprends pas .... si je ne fais qu'ajouter 0,1 à la valeur de je, comment obtient-il ces valeurs étranges? – JuiCe

+2

@JuiCe - Le problème est que l'arithmétique avec les doubles n'est généralement pas exacte. En particulier, la valeur (base 10) 0.1 n'a pas de représentation exacte en binaire. Ainsi, le dernier bit ou deux de la somme sera désactivé. Cette erreur d'arrondi s'aggrave souvent au fur et à mesure que vous ajoutez 0,1 à un nombre. –

+0

@JuiCe - En raison du même problème d'erreurs d'arrondi dans les calculs à virgule flottante, vous devez modifier votre boucle pour utiliser une variable de boucle 'int' et calculer' i/10.0' dans la boucle. Le problème est que vous ne pouvez pas facilement prédire de quel côté de 10,0 vous allez atterrir dans la dernière itération (après une centaine d'additions de pas exactement 0,1). De la façon dont vous avez écrit la boucle, il semble que vous ne voulez pas cette valeur 9.99999999999999999998 (après arrondi à 10.0). –

2
DecimalFormat dtime = new DecimalFormat("#.#"); 

for(double i = 0; i < 10 ; i+=0.1) 
{ 
    String i2= Double.valueOf(dtime.format(i)); 
    rVoltsList.add(Double.toString(i2)); 
} 
+2

serait-il .... rVoltsList.add (i2); ? – JuiCe

+0

Merci ...... @JuiCe – MAC

+0

Si cette approche est utilisée, la déclaration de 'dtime' devrait être retirée de la boucle. Il n'est pas nécessaire de créer un nouveau 'DecimalTime' à chaque itération. –

Questions connexes