J'ai un
float a = 1412.244019;
et j'ai besoin d'un arrondi à la seconde décimale la plus proche, comme 1412.24000000. Je comprends que si je veux présenter un avec seulement deux décimales, j'utilise% .2f, mais ce n'est PAS le cas. J'ai besoin du nouveau un pour des raisons mathématiques comme flotteur.
J'ai essayé quelques méthodes trouvées sur stackoverflow sans chance. Le plus évident que j'ai utilisé, je le mentionne ci-dessous, mais je n'ai toujours pas eu de chance de l'utiliser. Pouvez-vous voir pourquoi la magie ne se produit pas?
PS: Il fait parfois l'effet désiré, PAS toujours, ce qui me fait penser ... hmmm ...
Merci d'avance.
Code:
float a = 1412.244019;
NSLog(@"a is %f", a); //output a is 1412.244019
a = [[NSString stringWithFormat:@"%.2f", a] floatValue];
NSLog(@"a is %f", a); //output a is 1412.239990
MODIFIER:
SEMBLE comme lorsque j'utilise le flotteur a après la chirurgie ci-dessus, il considère que c'est 1412.240000 même si le NSLog dit différemment ... étrange. Mais je reçois ce que je veux, alors bravo pour le temps perdu à ne rien courir :)
MODIFIER J'aimerais vous choisir tous comme bonnes réponses, mais comme je ne peux en choisir qu'une, j'ai choisi la première bonne réponse avec des explications supplémentaires (des deux dernier).
Avez-vous essayé cela?
CGFloat val = 37.777779;
CGFloat rounded_down = floorf(val * 100) / 100; /* Result: 37.77 */
CGFloat nearest = floorf(val * 100 + 0.5) / 100; /* Result: 37.78 */
CGFloat rounded_up = ceilf(val * 100) / 100; /* Result: 37.78 */
source: arrondir le nombre à 2 décimales en C
Complémentaire: Vous n'avez tout simplement pas de contrôle sur la façon dont l'ordinateur stockera la valeur flottante.
Donc, ces valeurs arrondies peuvent ne pas être EXACTEMENT les valeurs décimales "évidentes", mais elles seront très très proches, et c'est la garantie maximale que vous aurez.
Vous faites cela dans Objective-C exactement comme vous le feriez dans C:
double notRounded = ...;
double rounded = round (notRounded * 100.0) / 100.0;
N'utilisez pas float - sauf si vous pouvez expliquer à quelqu'un exactement quelles sont vos raisons spécifiques d'utiliser float over double. float a une précision très limitée. Et utiliser un plafond ou un sol est idiot, car il existe une fonction standard parfaitement fine nommée "rond".
Ni float ni double ne peuvent exactement représenter la plupart des valeurs décimales, comme 12.24. Parce qu'il a une précision beaucoup plus élevée, le double vous permettra de vous rapprocher de 12,24. Par conséquent, il y a une énorme chance que NSLog affiche un nombre étrange pour (float) 12.24, comme 12.23999997394 ou autre, alors qu'il peut afficher 12.24 pour double.
Erreur dans cette ligne
a = [[NSString stringWithFormat:@"%.2f", a] floatValue];
le corriger pour
a = [NSString stringWithFormat:@"%.02f", a];
La valeur la plus proche de 1412.24 qu'un float
peut avoir est 1412.239990234375. Il existe une opération no qui peut produire un float
plus proche que cela, car le format des objets float
ne représente pas de valeurs plus proches. Demander à représenter 1412,24 dans float
revient à demander de représenter 2,5 dans int
. Ça ne peut tout simplement pas être fait.
Les options pour y faire face incluent:
float
sous-jacent.double
pour vous rapprocher (beaucoup plus près), mais ce ne sera toujours pas exactement 1412.24.float
en valeurs représentables (par exemple, mesurer dans d'autres unités de sorte que les valeurs souhaitées soient toutes exactement représentables en float
).NSDecimal
.Vous ne pouvez pas forcer une valeur flottante. Les flottants sont conçus pour être quelque peu approximatifs, car leur ampleur peut être grande, et comme vous n'avez que peu de bits à utiliser, il peut se rapprocher, mais pas exactement, exprimer un nombre décimal.
Une suggestion est de faire toute votre arithmétique en entier, multiplié par 100, puis en divisant lorsque vous voulez afficher votre résultat final. Vous pouvez avoir des nombres trop grands qui interdiraient cela.
Vous pouvez multiplier a par 100,0 et peut-être ajouter 0,5 pour l'arrondi, puis prendre la valeur int du résultat. Vous pouvez ensuite utiliser/100 pour obtenir la valeur avant la virgule décimale et% 100 pour obtenir les deux décimales.