Ajuste de precisión decimal, .net
Pregunta
Estas líneas en C #
decimal a = 2m;
decimal b = 2.0m;
decimal c = 2.00000000m;
decimal d = 2.000000000000000000000000000m;
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
Genera esta salida:
2
2.0
2.00000000
2.000000000000000000000000000
Así que se puede ver que la creación de una variable decimal de un literal me permite controlar la precisión.
- ¿Puedo ajustar la precisión de las variables decimales sin usar literales?
- ¿Cómo puedo crear b de una? ¿Cómo puedo crear b de c?
Solución
Preservar ceros como esto se introdujo en .NET 1.1 para más estricta conformidad con la especificación ECMA CLI.
Hay algo de información sobre esto en MSDN, por ejemplo, aquí .
Puede ajustar la precisión de la siguiente manera:
-
Math.Round (o de techo, piso etc) para disminuir la precisión (b desde c)
-
Multiplicar por 1.000 ... (con el número de decimales que desea) para aumentar la precisión - por ejemplo, multiplicar por 1,0 M para obtener b de a.
Otros consejos
Usted se acaba de ver diferentes representaciones de los mismos datos. La precisión de un decimal
será modificada para que sea tan grande como lo que debe ser (dentro de lo razonable).
Un número decimal es un punto flotante valor que consta de una señal, una valor numérico donde cada dígito en el valor varía de 0 a 9, y una factor de escala que indica el posición de un punto decimal flotante que separa la integral y partes fraccionarias del valor numérico.
La representación binaria de un decimal valor consiste en un signo de 1 bit, una número entero de 96 bits, y una escala factor utilizado para dividir el 96-bit número entero y especificar qué parte de ella es una fracción decimal. el escalado factor es implícitamente el número 10, elevado a un exponente que van desde 0 a 28. Por lo tanto, el binario la representación de un valor decimal se de la forma, ((-2 96 a 2 96 ) / 10 (0 a 28) ), donde -2 96 -1 es igual a MinValue, y 2 96 -1 es igual a MaxValue.
El factor de escala también se conserva ningún ceros en un número decimal. ceros no afectan a la valor de un número decimal en aritméticos o de comparación operaciones. Sin embargo, ceros pueden ser revelada por el método ToString si un Se aplica cadena de formato apropiado.
¿Qué hay de Math.Round (decimal d, Int decimales) ?
I encontré que podría "alterar" con la escala de multiplicar o dividir por un capricho 1.
decimal a = 2m;
decimal c = 2.00000000m;
decimal PreciseOne = 1.000000000000000000000000000000m;
//add maximum trailing zeros to a
decimal x = a * PreciseOne;
//remove all trailing zeros from c
decimal y = c / PreciseOne;
I puedo fabricar una suficientemente precisa 1 para cambiar los factores de escala por tamaños conocidos.
decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;
for (int i = 0; i < scaleFactorSize; i++)
{
scaleFactor *= scaleFactorBase;
}
decimal z = a * scaleFactor;
Es tentador confundir decimal
en SQL Server con decimal
en .NET; que son muy diferentes.
A decimal
SQL Server es un número de punto fijo cuya precisión y la escala están fijados cuando se define la columna o variable.
A decimal
NET es un número de coma flotante como float
y double
(siendo la diferencia que decimal
preserva precisión dígitos decimales mientras que float
y double
preservar precisión dígitos binarios). El intento de controlar la precisión de un decimal
.NET tiene sentido, ya que todos los cálculos se obtendrán los mismos resultados independientemente de la presencia o ausencia de ceros de relleno.
La pregunta es - lo que realmente necesita la precisión almacenado en el decimal, en lugar de mostrar el decimal a la precisión requerida. La mayoría de las aplicaciones internamente saben cómo es exacto que quieren ser y mostrar a ese nivel de precisión. Por ejemplo, incluso si un usuario introduce una factura por 100 en un paquete de cuentas, todavía se imprime como 100.00 usar algo como val.ToString ( "N2").
¿Cómo puedo crear b de una? ¿Cómo puedo crear b de c?
c a b es posible.
Console.WriteLine(Math.Round(2.00000000m, 1))
produce 2,0
A a B es complicado, ya que el concepto de la introducción de precisión es un poco extranjero a las matemáticas.
supongo que un horrible truco podría ser un ida y vuelta.
decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);
produce 2,0
Esto eliminará todos los ceros a la derecha del punto decimal y luego sólo se puede utilizar ToString()
.
public static class DecimalExtensions
{
public static Decimal Normalize(this Decimal value)
{
return value / 1.000000000000000000000000000000000m;
}
}
O, alternativamente, si quieres un número exacto de ceros a la derecha, por ejemplo 5, primera Normalizar () y luego se multiplica por 1.00000m.