6

Ich habe Zeitstempel Werte von Sensor Lesungen gelesen, aber da sie in Nanosekunden bereitgestellt werden, dachte ich, ich würde sie werfen, um zu verdoppeln und die Konvertierung vornehmen. Die resultierende Zahl ist ein 17-stelliger Wert plus das Trennzeichen.Formatieren Double zum Drucken ohne wissenschaftliche Notation mit Dezimalformat

Der Versuch, es direkt zu drucken, führt zu wissenschaftlicher Notation, die ich nicht möchte, also verwende ich eine DecimalFormat-Klasse, um es auf einen erwarteten Wert von 4 Dezimalstellen auszugeben. Das Problem ist, obwohl der Debugger selbst nach dem 'doubleValue()' Aufruf eine Anzahl von 17 Dezimalziffern anzeigt, zeigt der Ausgabe-String eine Anzahl von 15 Ziffern an.

Code:

... 
Double timestamp = (new Date().getTime()) +  // Example: 1.3552299670232847E12 
      ((event.timestamp - System.nanoTime())/1000000D); 
DecimalFormat dfmt = new DecimalFormat("#.####"); 

switch(event.sensor.getType()){ 
    case Sensor.TYPE_LINEAR_ACCELERATION: 
    case Sensor.TYPE_ACCELEROMETER: 
     accel = event.values.clone(); 
     String line = "A" + LOGSEPARATOR +    
      dfmt.format(timestamp.doubleValue()) + // Prints: 1355229967023.28 
... 

dachte ich, könnte dies ein Android Präzision Problem sein, aber der Debugger hat die Formatierungs die falsche Präzision als auch zeigt. Ich habe dies in einem lokalen Java-Programm getestet und beide Anrufe haben die gleiche Anzahl von Ziffern.

Ist dies ein DecimalFormat Fehler/Einschränkung? Oder mache ich etwas falsch?

+1

Ihr Problem ist, dass die Zahl nicht in dem Format paßt. Versuchen "##############.####". –

+0

Das habe ich dann auch probiert, habe es aber trotzdem überprüft, falls ich es vergessen hätte. Ein Format "####################. ####" (mit 7 zusätzlichen Ziffern) führt zum gleichen Ergebnis. – ravemir

+0

Verwenden Sie die java.util-Version von DecimalFormat oder eine Android-Version? –

Antwort

1

Es gibt tatsächlich einen Unterschied zwischen der DecimalFormat-Klasse von Java und Android, und sie geben unterschiedliche Ergebnisse aus, obwohl sie genau die gleichen Argumente haben.

Dies war genug für mich, um Henry Ansatz zu versuchen, und jetzt, wo ich habe ich sehe, dass ich ein extra 2 Plätze der Präzision gewonnen haben. Ich bin auch zuversichtlich, dass die Werte genau berechnet werden, da nur Summen und Multiplikationen beteiligt sind.

Dies ist der modifizierte Code, den ich am Ende mit:

... 
long javaTime = new Date().getTime(); 
long nanoTime = System.nanoTime(); 
long newtimestamp = javaTime * 1000000 +   // Compute the timestamp 
      (event.timestamp - nanoTime);   // in nanos first 
String longStr = Long.valueOf(newtimestamp).toString(); 
String tsString = longStr.substring(0, longStr.length()-6) +// Format the output string 
      "." + longStr.substring(longStr.length()-6); // to have the comma in the 
                  // correct space. 
... 
0

Forschte auch mit String.format mit denselben Ergebnissen.

Double timestamp = 1.3552299670232847E12; 
System.out.println("it was " + timestamp); 
System.out.println("and now " + String.format("%.4f", timestamp)); 

Und dies ist die Ausgabe:

12-12 15:48:58.255: I/System.out(2989): it was 1.3552299670232847E12 
12-12 15:48:58.255: I/System.out(2989): and now 1355229967023,2800 

Vielleicht hast du recht und es ist ein Android-Präzision Problem, als ob Sie es in Java versuchen, die Ausgabe korrekt ist: http://ideone.com/PBOiet

I werde googeln ...

+0

Keine neuen Erkenntnisse? – ravemir

2

Ein Double in Java hat eine Mantisse von nur 52 Bit (zählt die versteckte 1 seine 53 Bit). Dies entspricht 15-16 Dezimalstellen (53 * log10 (2)). Jede Ziffer danach ist zufällig und deshalb ist es sinnvoll, wenn die Konvertierungsfunktion den Ausgang nach 15 Dezimalstellen abschneidet.

Da Sie den großen Zahlenbereich, den Double bietet, nicht benötigen, warum nicht den Wert so lang halten? Dies würde Ihnen 63 signifikante Bits geben (64 -1 für das Zeichen).

+0

Das war meine Argumentation: Ich muss Nanosekunden in Millisekunden umrechnen, berechnet mit zwei Longs. Aber ich hatte nicht umgekehrt gedacht: Millisekunden in Nanosekunden zu ändern, was keine Fließkommadaten erfordert. Auf diese Weise kann ich die Präzision von den Longs beibehalten und muss das Komma beim Ausdrucken nur um 6 Stellen nach links verschieben. Lass mich das testen und ich melde mich bei dir. – ravemir

+0

Es hat funktioniert! Ich habe nicht nur die anderen zwei Plätze bekommen, sondern zusätzlich noch 2. Das Seltsame ist, ich hatte erwartet, dass die letzten zwei Zeichen, die mit der vorherigen Methode berechnet wurden, nur Zufallszahlen waren, aber sie stimmen mit denen in meinem neu berechneten langen Wert überein. – ravemir

+0

Ich werde dir die Bounty gewähren und meine eigene Antwort formatiert hinzufügen. Ich fühle mich jedoch etwas dumm, weil ich daran gedacht habe, etwas Ähnliches zu tun, aber ich habe mich nicht darum gekümmert, dass es zwielichtig wäre. – ravemir

Verwandte Themen