2009-01-04 14 views
7

¿Puede alguien explicar por qué int (0.4 * 10.0) es 4 pero int ((2.4 - 2.0) * 10.0) es 3?Convertir float a int en F #

Y luego también explique cómo obtener 4. es decir, ¿realmente tengo que hacer int (System.Math.Round((2.4 - 2.0) * 10.0))?

Es tan feo para algo que debería ser tan simple.

+2

Cabe señalar que esto no es un "problema" específico F #, sino en la naturaleza de la mayoría de los idiomas, por lo al menos todos de .NET. –

Respuesta

11

La doble representación de 2.4 - 2.0 es 0.399999999999. Cuando convierte un número a int, la parte decimal se trunca para que 3.999999999 se trunque a 3.

+1

Eso es correcto, si quiere obtener 4.0 entonces puede usar Math.Round: Math.Round ((2.4 - 2.0) * 10.0) – Robert

1

Los números de coma flotante no son de precisión infinita. Algunos números pueden representarse perfectamente (cualquier cosa que involucre potencias de dos, por ejemplo, 1, 1/2 = 0.5, 1/4 = 0.25, etc.), y otros no (por ejemplo, 1/3 no puede descomponerse exactamente en una secuencia finita) de poderes de dos). A menudo, cortar el final de la serie infinita hace que la versión codificada de un número sea ligeramente más pequeña que su valor real.

Combine esto con el hecho de que el (int) operador trunca en lugar de rondas, y se puede ejecutar en los casos en que una operación que debe producir resultados en 4,0 3.999999999991 lugar, que se convierte 3.

En cualquier momento está intentando convertir flotantes/dobles en enteros, quiere pensar cuidadosamente sobre qué operador desea usar: truncar (redondear hacia abajo), redondear hacia arriba o redondear hacia el más cercano.

Dado que este es un problema con las representaciones de punto flotante, esto es cierto no solo en F #, sino también en C# y (IIRC) Java y en otros lenguajes.

5

Y luego también, por favor explicar cómo llegar 4. decir, ¿Realmente tengo que hacer

int (System.Math.Round ((2,4 - 2,0) * 10,0))

es sólo tan feo para algo que debería ser tan simple.

Por supuesto que no, simplemente definen

let round x = int System.Math.Round(x) 
4

En realidad, en .Net existe un tipo de datos decimal que le ayude con este problema, si sus números se pueden representar exactamente como fracciones decimales.

2.4m - 2.0m == 0.4m 
2.4 - 2.0 != 0.4 
2

para convertir un número float a un uso int:

let i = Convert.ToInt32(f)

+0

Solo una nota para usuarios nuevos (como yo): necesita 'abrir sistema' primero – sebhofer