2009-07-23 4 views
0

Je pourrais utiliser de l'aide. Après quelques jours frustrants d'essais et d'erreurs, j'obtiens des résultats incohérents en écrivant des préférences à NSUserDefaults.iPhone SDK NSUserDefaults ne pas enregistrer les valeurs correctes

Voici les lignes consécutives de code:

 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 est une chaîne constante.

Comme vous pouvez le voir, je consigne la valeur actuelle de la clé, puis j'enregistre la valeur que j'ai l'intention de stocker, synchroniser, puis relire la valeur stockée. Cela semble simple pour moi, mais voici la sortie du débogueur:

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 

Je vois la valeur initiale 0, la valeur prévue à la fin 571, et la valeur lue à partir du cache qui est de 6 secondes d'arrêt.

Je ne sais pas d'où vient la nouvelle valeur par défaut. Des idées? J'ai un comportement similaire sur l'appareil et sur le simulateur.

Merci Brad

Répondre

1

Comment définissez-vous endTime. Est-ce un double? Je suis relativement certain que ce n'est pas un problème NSUserDefaults, mais un problème mathématique à virgule flottante.

270018630.916571 est de 16 chiffres décimaux, ce qui prend ~ 48 bits de données pour stocker la mantisse. Un point flottant est 32 bits, mais 1 bit est un bit de signe, 8 bits d'exposant et 23 bits de mantisse. Cela signifie que la valeur que vous voyez est beaucoup plus grande qu'un flotteur peut contenir, et une certaine quantité de précision perdue est attendue. Même si vous le tronquez à 270018630, il faut encore ~ ​​28 bits de percision pour l'exprimer, ce qui signifie qu'il doit être arrondi par incréments plus grand qu'un nombre entier.

Les nombres à virgule flottante ne vous permettent pas d'exprimer par magie des nombres plus grands que des nombres entiers avec le même nombre de bits. Ils créent la capacité de stocker de grands nombres en faisant varier l'écart entre les nombres et en utilisant des métadonnées (l'exposant) pour le suivre. Wikipedia a un explanation décent de la façon dont ils travaillent.

+0

Je crois que vous avez raison. J'essayais de stocker NSTimeIntervals qui sont définis comme doubles. Cela explique pourquoi la fonctionnalité était étroite dans certains cas, incohérente dans d'autres, et parfaite pour les petits nombres. –

Questions connexes