Double to print formatting without scientific notation using DecimalFormat

I read the timestamp values ​​from the sensor readings, but since they are provided in nanoseconds, I thought that I would double them and make the conversion. The resulting number is a 17-digit value, plus a separator.

Trying to print it directly leads to a scientific notation that I don’t want, so I use the DecimalFormat class to output it to the expected value of 4 decimal places. The problem is that although the debugger shows the number of 17 decimal digits, even after calling "doubleValue ()", the output line shows me a number of 15 digits.

The 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 ... 

I thought this might be an android precision issue, but the debugger also has the wrong accuracy. I tested this in a local Java program, and both calls have the same number of digits.

Is this a DecimalFormat error / limitation? Or am I doing something wrong?

+6
source share
3 answers

There is really a difference between the Java class and the Android DecimalFormat, and they produce different results, even though they take the same arguments.

That was enough for me to try Henry's approach, and now that I see that I got an extra 2 places of accuracy. I am also sure that the values ​​are calculated accurately, since only sums and multiplications are involved.

This is the modified code that I ended up using:

 ... 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. ... 
+1
source

Double in Java has a mantiss of only 52 bits (counting hidden 1 of its 53 bits). This is equivalent to 15-16 decimal places (53 * log10 (2)). Each digit after this is random and therefore it makes sense for the conversion function to cut the output after 15 decimal places.

Since you don't need the large range of numbers that double provides, why not keep the value for so long? This will give you 63 significant bits (64 -1 for a character).

+2
source

Conducted some research with String.format, as well as with the same results.

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

And this is the result:

 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 

You may be right, and this is the Android accuracy issue, as if you were trying to use it in Java, the output is correct: http://ideone.com/PBOiet

I will continue the search engine ...

0
source

All Articles