0

私はいくつかの助けを使うことができます。イライラする数日間の試行錯誤の後、NSUserDefaults への設定の書き込みで一貫性のない結果が得られます。

連続するコード行は次のとおりです。

        NSLog(@"startTimer(): End Time defaults: %f\n", [defaults floatForKey:kEndTimeKey]);
    NSLog(@"startTimer(): new End Time: %f\n", endTime);
    [defaults setFloat:endTime forKey:kEndTimeKey];
    [defaults synchronize];
    NSLog(@"startTimer(): stored EndTimeKey: %f\n", [defaults floatForKey:kEndTimeKey]);

kEndTimeKey は定数文字列です。

ご覧のとおり、キーの現在の値をログに記録してから、保存する予定の値をログに記録し、同期してから、保存された値を再度読み取ります。私には簡単に思えますが、デバッガーの出力は次のとおりです。

2009-07-22 22:05:43.263 TimerTest3[1584:207] startTimer(): End Time defaults: 0.000000
2009-07-22 22:05:43.266 TimerTest3[1584:207] startTimer(): new End Time: 270018630.916571
2009-07-22 22:05:43.287 TimerTest3[1584:207] startTimer(): stored EndTimeKey: 270018624.000000

元の値 0、571 で終わる意図した値、および 6 秒ずれているキャッシュから読み取られた値が表示されます。

新しいデフォルトがどこから来たのかわかりません。何か案は?デバイスとシミュレーターで同様の動作が得られます。

ありがとうブラッド

4

1 に答える 1

1

endTime をどのように設定していますか。ダブルですか?これは NSUserDefaults の問題ではなく、浮動小数点演算の問題であると比較的確信しています。

270018630.916571 は 16 桁の 10 進数で、仮数を格納するために最大 48 ビットのデータを使用します。浮動小数点は 32 ビットですが、その 1 ビットは符号ビット、指数は 8 ビット、仮数は 23 ビットです。これは、表示されている値が float が保持できるよりもはるかに大きく、精度がいくらか失われることが予想されることを意味します。270018630 に切り捨てても、表現するのに最大 28 ビットの精度が必要です。つまり、整数よりも大きい増分で丸める必要があります。

浮動小数点数では、同じビット数の int よりも大きな数を魔法のように表現することはできません。数値間のギャップを変化させ、メタデータ (指数) を使用して追跡することで、大きな数値を格納する機能を作成します。ウィキペディアには、それらがどのように機能するかについての適切な説明があります。

于 2009-07-23T08:03:38.207 に答える