2010-04-07 15 views
9

Cualquier forma inteligente para convertir un flotador como esto:C# flotador a la conversión decimal

float f = 711989.98f; 

en un decimal (o doble) sin perder precisión?

He intentado:

decimal d = (decimal)f; 
decimal d1 = (decimal)(Math.Round(f,2)); 
decimal d2 = Convert.ToDecimal(f); 
+0

Más detalles: estoy interfaz con un viejo servicio web que envía este enorme objeto que tiene algunos campos como flotador. Cuando hago la conversión a decimal kaboom ... ¡no más centavos! – Adrian4B

+0

si esto proviene de un servicio web en el cable, probablemente sea XML, lo que significa que no hay flotación o decimales, solo cadenas. Mire dónde se convierten estas cadenas al formato "interno" – mfeingold

Respuesta

11

Es demasiado tarde, el octavo dígito se perdió en el compilador. El tipo de flotador puede almacenar solo 7 dígitos significativos. Tendrás que volver a escribir el código, por lo que la asignación a doble o decimal resolverá el problema.

+0

gracias He cambiado el tipo de campo en objeto mapeado de flotante a decimal y resolví el problema de conversión que estaba sucediendo durante la deserialización. – Adrian4B

1

han intentado?

decimal.TryParse() 

http://forums.asp.net/t/1161880.aspx

No hay conversiones implícitas entre flotador/doble y decimal. Las conversiones numéricas implícitas siempre están garantizadas sin pérdida de precisión o magnitud y no causarán una excepción.

+1

No se garantiza que las conversiones implícitas carezcan de precisión. La conversión de '9007199791611905' a' double' arrojará '9007199791611904'. Convirtiendo directamente a 'float' rendirá' 9007200328482816'. La conversión a 'double' y luego a' float' arrojará '9007199254740992' (que está desactivado por más que si el número se hubiera convertido directamente en' float'). Además, aunque los compiladores permiten la conversión implícita de 'float' a' double', es mucho más probable que esas conversiones sean erróneas que las conversiones de 'double' a' float', que no están permitidas, pero deberían serlo. – supercat

+1

@supercat aparentemente [puede convertir sin problemas 'float' a' double'] (http://stackoverflow.com/q/40550861/24874). Sin embargo, convertir "doble" a "flotar" es probable que introduzca errores, dependiendo del valor "doble" específico en cuestión. –

+0

@DrewNoakes: si uno ha utilizado un cálculo iterativo para calcular la posición de un objeto usando el tipo 'double', y luego desea dibujarlo utilizando rutinas gráficas que acepten' float', la conversión a 'float' eliminaría la precisión que generalmente sería inútil, incluso si se conserva; recortar la precisión casi con seguridad sería consistente con la intención del programador. Por el contrario, si algún código, p.divide un 'int' o' long' por un 'float' y almacena el resultado en un' double', entonces, a menos que el programador explícitamente arroje el resultado de la división a 'float', no presumiría que el programador ... – supercat

1

Perdió la precisión en el momento en que escribió 711989.98f.

711989.98 es decimal. Con f al final le está pidiendo al compilador que lo convierta en flotante. Esta conversión no se puede hacer sin perder precisión.

Lo que probablemente quiera es decimal d = 711989.98m. Esto no perderá precisión.

+0

Su ejemplo solo usa un doble, ¿verdad? Todavía podría perder precisión para un número diferente. Simplemente ponga una 'm' en el extremo y haga que el literal sea un decimal para comenzar. –

1

Esto puede ser un error del compilador porque parece que un float válido debe convertir directamente a un decimal. pero no lo hará sin perder resolución. Convirtiendo 125.609375 de flotante a decimal perderá resolución. Sin embargo, convertirlo de flotante a doble y luego a doble a decimal mantendrá la resolución.

float float_val = 125.609375f; 

    decimal bad_decimal_val = (decimal)float_val; //125.6094 

    double double_val = (double)float_val; 
    decimal good_decimal_val = (decimal)double_val; 
Cuestiones relacionadas