2010-09-28 14 views
37

esto lo que estoy tratando de lograr:doble a 3 cifras decimales

Si un doble tiene más de 3 cifras decimales, quiero truncar cualquier cifras decimales más allá de la tercera. (No redonda.)

Eg.: 12.878999 -> 12.878 

Si un matrimonio tiene menos de 3 decimales, dejar sin cambios

Eg.: 125 -> 125 
     89.24 -> 89.24 

me encontré con este comando:

double example = 12.34567; 
double output = Math.Round(example, 3); 

Pero yo no quiero redondo. De acuerdo con el comando publicado anteriormente, 12.34567 -> 12.346

quiero truncar el valor, de modo que se convierte en: 12.345

+0

Ver http://stackoverflow.com/questions/3797342/how-do-i-round-down-a-decimal-to-2 -decimal-places-in-net –

Respuesta

53

de dobles no tienen decimales lugares - no se basan en dígitos decimales para empezar. Podría obtener "el doble más cercano al valor actual cuando se trunca a tres dígitos decimales", pero aún así no sería exactamente el mismo. Sería mejor usar decimal.

Dicho esto, si es sólo la forma en que el redondeo ocurre eso es un problema, puede utilizar Math.Truncate(value * 1000)/1000; cuales puede hacer lo que quiera. (No quiere redondeando en absoluto, por lo que suena). Sin embargo, aún es potencialmente "dudoso", ya que el resultado todavía no tendrá tres decimales. Si usted hizo lo mismo con un valor decimal, sin embargo, haría trabajo:

decimal m = 12.878999m; 
m = Math.Truncate(m * 1000m)/1000m; 
Console.WriteLine(m); // 12.878 

EDIT: Como LBushkin señaló, debe ser clara entre el truncamiento de pantalla propósitos (que por lo general se puede hacer en un especificador de formato) y truncando para realizar más cálculos (en cuyo caso lo anterior debería funcionar).

+0

yup ... no hay redondeo. Voy a probar esto. Gracias. – xbonez

+2

+1 para señalar que este es un trabajo para 'decimal'. –

+4

Si el "truncamiento" es solo para fines de visualización, eso se puede lograr cuando el valor se convierte en una representación de cadena. Esto preservaría la precisión y evitaría algunos de los inconvenientes de tratar de realizar una manipulación decimal precisa de un número de coma flotante. – LBushkin

7

Multiplicar por 1.000 a continuación, utilizar Truncate y se divide por 1000.

+0

El enlace que desea es http://msdn.microsoft.com/en-us/library/c2eabd70.aspx –

+0

Sí, tiene razón. Mismo método, pero la doble sobrecarga en lugar de decimal. – Josh

3

Se puede utilizar:

double example = 12.34567; 
double output = ((double) ((int) (example * 1000.0)))/1000.0 ; 
+0

Mi única preocupación aquí es que la conversión a int no solo corta los dígitos después de la posición decimal, sino que restringe el rango del valor a lo que una int puede contener. Un doble puede ser mucho más grande que un int. –

5

Si su propósito en el truncamiento de los dígitos es por razones de presentación, a continuación, sólo sólo tiene que utilizar un formato adecuado al convertir el doble en una cadena.

Los métodos como String.Format() y Console.WriteLine() (y otros) le permiten limitar el número de dígitos de precisión con los que se formatea un valor.

Intentar "truncar" los números de coma flotante es desaconsejable - los números de coma flotante no tienen una representación decimal precisa en muchos casos. Aplicar un enfoque como escalar el número, truncarlo y luego escalarlo podría cambiar fácilmente el valor a algo bastante diferente de lo que esperabas para el valor "truncado".

Si necesita representaciones decimales exactos de un número que usted debe utilizar en lugar de decimaldouble o float.

+0

Esto resume todos los buenos consejos en un solo lugar. –

32

No puedo pensar en una razón para perder precisión explícitamente fuera de los propósitos de visualización. En ese caso, simplemente use el formato de cadena.

double example = 12.34567; 

Console.Out.WriteLine(example.ToString("#.000")); 
+1

+1 para cuestionar las premisas de la pregunta. –

+4

Lo necesito porque estoy haciendo coincidir los valores de un archivo XML con los almacenados en un DB. Ambas partes completan ambas fuentes. El que rellena el Db elige no completar nada más de 3 decimales, mientras que el archivo XML a menudo puede tener hasta 8 lugares decimales – xbonez

+0

@StevenSudit Y otro posible caso de uso, como el mío, es donde tengo un campo DB eso solo puede tomar 10 caracteres, pero la forma tiene un campo lb -> kg donde se realiza un cálculo y puede dar un número> 10 caracteres. A veces solo quieres unos pocos dígitos significativos y no quieres truncar ni redondear, pero tienes limitaciones en la cantidad de cifras que puedes almacenar. Así que desestimó cuestionar este caso de uso, ya que es muy común cuando se almacenan números en un campo DB, no se lo repite. Afortunadamente tiene una respuesta útil, así que votaré mejor. – vapcguy

1

Buenas respuestas arriba, si está buscando algo reutilizable aquí está el código. Tenga en cuenta que es posible que desee comprobar el valor de los lugares decimales, y esto puede desbordarse.

public static decimal TruncateToDecimalPlace(this decimal numberToTruncate, int decimalPlaces) 
{ 
    decimal power = (decimal)(Math.Pow(10.0, (double)decimalPlaces)); 

    return Math.Truncate((power * numberToTruncate))/power; 
} 
13
double example = 3.1416789645; 
double output = Convert.ToDouble(example.ToString("N3")); 
+0

Necesitaba solamente algunos decimales después del ejemplo. Esto ayudó. :) –

1

En C lang:

double truncKeepDecimalPlaces(double value, int numDecimals) 
{ 
    int x = pow(10, numDecimals); 
    return (double)trunc(value * x)/x; 
} 
Cuestiones relacionadas