2012-04-06 20 views
6

Me pregunto si existe alguna manera de poder corregir números de coma flotante de manera fácil y segura.Corrección de números en coma flotante

Por ejemplo,

Cuando entró: "32 + 32.1" Resultado: "64,0999999999999"

También debo mencionar que esto ocurre con bastante frecuencia cuando se utiliza la notación científica. "(2.3 x 10^23) * (1.452 * 10^23)" Devuelve: "3.339599999999999999e + 46"

Y, por último, a veces el número que se devuelve es: ex. 123,0000000000001

Gracias por la ayuda!

EDITAR

La respuesta que fue aprobado es grande. Pero lo que encontré funcionó para mí fue usar% g con un doble en NSString stringWithFormat. % g parece redondear todo bastante apropiadamente. ej.

answer.text = [NSString [email protected]" %g ", doubleAnswer]; 

El uso de dobles a través de sus cálculos y luego usar ese método parecía funcionar para mí, y espero que esto ayude a otros también. Si esta no es la respuesta que buscas, ¡mira la respuesta aprobada!

Respuesta

8

Los números de coma flotante no representan números específicos muy bien. Usar dobles hará que esto ocurra con menos frecuencia, pero aún tendrás el problema. Para obtener una descripción técnica de cómo se almacenan los números de coma flotante (y por qué tenemos este problema en primer lugar), consulte este artículo de Wikipedia: IEEE 754-1985. (Básicamente, los flotadores se almacenan como una representación binaria del valor y solo tienen tantos bits para usar, por lo que se agotan rápidamente y tienen que redondear al valor más cercano que son capaces de representar).

Normalmente no No se preocupe por el +/- 0000001 y simplemente formatéelo cuando desee mostrarlo al usuario con el número apropiado de puntos decimales y se redondeará. Internamente, en realidad no importa cómo se almacena.

Por ejemplo, si desea mostrar el "número" se puede hacer algo como esto:

float myFloat = 32 + 32.1; 
NSString *result = [NSString stringWithFormat:%@"%.2f", myFloat]; 
// result will contain 64.10 

Si no desea que un número fijo de puntos decimales, también puede utilizar el flotador cadena de la capacidad de conversión de NSNumber:

float myFloat = 32 + 32.1; 
NSNumber *myNumber = [NSNumber numberWithFloat:myFloat]; 
NSString *result = [myNumber stringValue]; 
// result will contain 64.1 

NSDecimalNumber se hará cargo de todo esto para usted, pero es un poco más complicado e implica un mayor gasto, pero aquí hay un ejemplo para empezar:

NSDecimalNumber *num1 = [NSDecimalNumber decimalNumberWithString:@"32"]; 
NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithString:@"32.1"]; 
// Or since you use exponents: 
// NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithMantissa:321 exponent:-1 isNegative:NO]; 

NSDecimalNumber *myNumber = [num1 decimalNumberByAdding:num2]; 
NSString *result = [myNumber stringValue]; 
// result will contain 64.1 
+1

ahh cierto cierto, pero ¿y si quisiera mostrarlo como 62.1, pero aún así dejar la posibilidad de mostrar 64.1065 por ejemplo (esto es lo que estoy buscando por cierto, gracias) –

+1

Entonces o necesita rastrear los decimales que desea mostrar (desordenados) o no usar float y moverse al tipo de variable de antera (probablemente 'NSDecimalNumber'). – lnafziger

+1

Lo intentaré. –

2

No se puede "corregir" un número de punto flotante porque los números de punto flotante, simplemente no pueden representar el número que desea.

números de punto flotante son muy imprecisos y, en general, no debe ser utilizado para todo lo que implica una gran cantidad de cálculos debido a que el error acumulativo es a menudo catastróficamente mal.

Use un double en su lugar. Pueden representar una gama de valores mucho mayor y, como resultado, pueden representar muchos más valores con bastante precisión. Si eso no es lo suficientemente bueno, tendrás que moverte a algo con más precisión. Posiblemente NSDecimalNumber.

Cuestiones relacionadas