6

我一直在阅读传感器读数的时间戳值,但由于它们是以纳秒提供的,因此我认为我会将它们转换为double并进行转换。结果的数字是一个17位数值,加上分隔符。格式化使用DecimalFormat不使用科学计数法进行双打印

试图直接打印它会导致科学记数法,这是我不想要的,所以我使用DecimalFormat类将其输出到4位小数位的期望值。问题是,即使调试器显示17位十进制数字,即使在调用'doubleValue()'后,输出字符串也会显示15位数字。

代码:

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

我想这可能是一个机器人的精度问题,但调试器显示错误的精确度以及格式化。我已经在本地java程序中测试了这个,并且这两个调用都有相同数量的数字。

这是一个DecimalFormat错误/限制吗?或者我做错了什么?

+1

你的问题是,数量不适合的格式。试试“##############。####”。 –

+0

我也尝试过,但无论如何我都忘记了。格式“####################。####”(带有7个额外数字)获得相同的结果。 – ravemir

+0

您是使用DecimalFormat的java.util版本还是Android版本? –

回答

1

Java和Android的DecimalFormat类确实有区别,尽管采用了完全相同的参数,但它们输出的结果不同。

这足以让我尝试亨利的方法,现在我已经看到我已经获得了额外的2个精度。我也确信这些数值是准确计算的,因为只涉及总和和乘法。

这是修改后的代码我最终使用:

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

正在用String.format进行一些研究,并得到相同的结果。

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

这是输出:

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 

也许你是对的,并因为如果你尝试在Java中这是一个Android的精度问题,输出是正确的:http://ideone.com/PBOiet

我将继续使用谷歌搜索...

+0

没有新的发现? – ravemir

2

在Java中的双重尾数只有52位(计数隐藏1其53位)。这相当于15-16位小数(53 * log10(2))。之后的每个数字都是随机的,因此转换函数在小数点后15位切分输出是有意义的。

由于您不需要double提供的大数字范围,为什么不保持这个值长呢?这会给你63个有效位(符号为64 -1)。

+0

这是我的推理:我需要将纳秒转换为以毫秒为单位计算的长度。但我还没有想过:将毫秒变为纳秒,而不需要浮点数据。这样我就可以保持长时间的精确度,并且在打印出来时,我只需要将6个逗号移到左侧。让我测试一下,我会回到你身边。 – ravemir

+0

它的工作!我不仅得到了另外两个地方,还有另外两个地方。奇怪的是,我期待用前面的方法计算出来的最后两个字符只是随机数,但它们与我新计算的长整型值内的字符相匹配。 – ravemir

+0

我会授予您赏金,并添加自己的格式化答案。不过,我觉得有些愚蠢,因为我想过做类似这样的事情,但没有打扰/认为它是狡猾的。 – ravemir

相关问题