格式化使用DecimalFormat在没有科学记数法的情况下打印Double

时间:2012-12-12 15:11:46

标签: java android string-formatting floating-accuracy double-precision

我一直在读取传感器读数的时间戳值,但由于它们以纳秒为单位提供,我想我会将它们加倍并进行转换。结果数字是一个17位数字加上分隔符。

尝试直接打印它会产生科学记数法,这是我不想要的,因此我使用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
...

我认为这可能是一个android精度问题,但调试器的格式化程序也显示错误的精度。我已经在本地java程序中对此进行了测试,并且两个调用都具有相同的数字位数。

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

3 个答案:

答案 0 :(得分:2)

Java中的double有一个只有52位的尾数(将隐藏的1计算为53位)。这相当于15-16位小数(53 * log10(2))。之后的每个数字都是随机的,因此转换函数在15位小数后减少输出是有意义的。

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

答案 1 :(得分: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.
...

答案 2 :(得分: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

也许你是对的,这是一个Android精度问题,就像你在Java中尝试一样,输出是正确的:http://ideone.com/PBOiet

我会继续谷歌搜索...