Digamos que tengo un valor de 3.4679 y quiero 3.46, ¿cómo puedo truncarlo a dos decimales sin redondear hacia arriba?
He intentado lo siguiente, pero los tres me dan 3,47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
Esto devuelve 3.46, pero parece sucio de alguna manera:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
Sería más útil tener una función completa para el uso en el mundo real de truncar un decimal en C #. Esto podría convertirse en un método de extensión decimal bastante fácil si quisiera:
Si necesita VB.NET, intente esto:
Entonces úsalo así:
o
fuente
Utilice el operador de módulo:
resultado: 0.54
fuente
0.5400
... La respuesta de D. Nesterov a continuación produjo lo esperado0.54
.$"{0.54m:C}"
produce"$0.54"
y sí,$"{0.5400m:C}"
produce"$0.54"
.Método universal y rápido (sin
Math.Pow()
/ multiplicación) paraSystem.Decimal
:fuente
Un problema con los otros ejemplos es que multiplican el valor de entrada antes de dividirlo. Hay un caso límite aquí en el que puede desbordar decimal multiplicando primero, un caso límite, pero algo con lo que me he encontrado. Es más seguro tratar la parte fraccionaria por separado de la siguiente manera:
fuente
Dejaré la solución para números decimales.
Algunas de las soluciones para decimales aquí son propensas a desbordarse (si pasamos un número decimal muy grande y el método intentará multiplicarlo).
La solución de Tim Lloyd está protegida contra desbordamientos, pero no es demasiado rápida.
La siguiente solución es aproximadamente 2 veces más rápida y no tiene un problema de desbordamiento:
fuente
Truncate
método se agrupará junto con los nativos .net, lo que brinda al usuario una experiencia perfecta.Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));
falla debido a esto. Si especifica el redondeo "normal" (AwayFromZero) en la llamada Math.Round,Assert.AreEqual(0m, 0m.TruncateEx(1));
fallaMidpointRounding.AwayFromZero
un código específico para manejar el valor 0.Esta es una pregunta antigua, pero muchas respuestas no funcionan bien o se desbordan para grandes números. Creo que la respuesta de D. Nesterov es la mejor: robusta, simple y rápida. Solo quiero agregar mis dos centavos. Jugué con los decimales y también revisé el código fuente . De la
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
documentación del constructor .Sabiendo esto, mi primer enfoque fue crear otro
decimal
cuya escala corresponda a los decimales que quería descartar, luego truncarlo y finalmente crear un decimal con la escala deseada.Este método no es más rápido que el de D. Nesterov y es más complejo, así que jugué un poco más. Supongo que tener que crear un auxiliar
decimal
y recuperar los bits dos veces lo hace más lento. En mi segundo intento, manipulé los componentes devueltos por el método Decimal.GetBits (Decimal d) yo mismo. La idea es dividir los componentes por 10 tantas veces como sea necesario y reducir la escala. El código se basa (en gran medida) en el método Decimal.InternalRoundFromZero (ref Decimal d, int decimalCount) .No he realizado pruebas de rendimiento rigurosas, pero en un procesador MacOS Sierra 10.12.6, Intel Core i3 de 3,06 GHz y apuntando a .NetCore 2.1, este método parece ser mucho más rápido que el de D. Nesterov (no daré números desde , como he mencionado, mis pruebas no son rigurosas). Depende de quien implemente esto evaluar si las ganancias de rendimiento se compensan o no con la complejidad adicional del código.
fuente
¿Que este trabajo para usted?
fuente
¿
((long)(3.4679 * 100)) / 100.0
Darías lo que quieres?fuente
Aquí hay un método de extensión:
fuente
Si no se preocupa demasiado por el rendimiento y el resultado final puede ser una cadena, el siguiente enfoque será resistente a los problemas de precisión flotante:
fuente
Aquí está mi implementación de la función TRUNC
fuente
que hay de esto
fuente
Aparte de las soluciones anteriores, hay otra forma de lograrlo.
fuente
En algunas condiciones, esto puede ser suficiente.
Tenía un valor decimal de SubCent = 0.0099999999999999999999999999M que tiende a formatear a | SubCent: 0.010000 | via
string.Format("{0:N6}", SubCent );
y muchas otras opciones de formato.Mi requisito era no redondear el valor de SubCent, pero tampoco registrar todos los dígitos.
Lo siguiente cumplió con mi requisito:
Que devuelve la cadena: | SubCent: 0.0099999 |
Para acomodar el valor que tiene una parte entera, lo siguiente es un comienzo.
Que devuelve la cadena:
fuente
estoy usando esta función para truncar el valor después del decimal en una variable de cadena
fuente
Esto es lo que hice:
restar dos números ingresados sin redondear los decimales hacia arriba o hacia abajo. porque las otras soluciones no me funcionan. No sé si funcionará para otros, solo quiero compartir esto :) Espero que funcione para aquellos que están encontrando una solución a un problema similar al mío. Gracias
PD: soy un principiante, así que siéntete libre de señalar algo sobre esto. : D esto es bueno si realmente estás tratando con dinero, por los centavos, ¿verdad? solo tiene 2 lugares decimales y redondearlo es un no no.
fuente
fuente
fuente
En realidad, quieres 3.46 de 3.4679. Esto es solo una representación de caracteres. Por lo tanto, no hay nada que ver con la función matemática. La función matemática no está destinada a hacer este trabajo. Simplemente use el siguiente código.
fuente
qué pasa
fuente