6

センサーの読み取り値からタイムスタンプ値を読み取っていますが、ナノ秒単位で提供されるため、2倍にキャストして変換することを考えました。結果の数値は、17桁の値に区切り文字を加えたものです。

直接印刷しようとすると科学的記数法になりますが、これは望ましくないので、DecimalFormatクラスを使用して、小数点以下4桁の期待値に出力します。問題は、デバッガーが10進数の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のバグ/制限ですか?それとも私は何か間違ったことをしていますか?

4

3 に答える 3

2

Javaのdoubleの仮数は、わずか52ビットです(非表示の1を53ビットとして数えます)。これは小数点以下15〜16桁に相当します(53 * log10(2))。この後のすべての桁は一種のランダムであるため、変換関数が小数点以下15桁の後に出力をカットすることは理にかなっています。

doubleが提供する大きな数値範囲は必要ないので、値を長く維持してみませんか?これにより、63の有効ビット(符号は64 -1)が得られます。

于 2012-12-21T15:21:25.113 に答える
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.
...
于 2012-12-21T18:03:10.380 に答える
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

グーグルし続けます...

于 2012-12-12T15:56:17.653 に答える