Quiero un método de redondeo en valores dobles en C#. Necesita poder redondear un valor doble a cualquier valor de precisión de redondeo. Mi código en la mano se ve así:Redondeo de valores dobles en C#
public static double RoundI(double number, double roundingInterval) {
if (roundingInterval == 0.0)
{
return;
}
double intv = Math.Abs(roundingInterval);
double sign = Math.Sign(number);
double val = Math.Abs(number);
double valIntvRatio = val/intv;
double k = Math.Floor(valIntvRatio);
double m = valIntvRatio - k;
bool mGreaterThanMidPoint = ((m - 0.5) >= 1e-14) ? true : false;
bool mInMidpoint = (Math.Abs(m - 0.5) < 1e-14) ? true : false;
return (mGreaterThanMidPoint || mInMidpoint) ? sign * ((k + 1) * intv) : sign * (k * intv);
}
Así fase en el (100, 3) debe dar 99 y fase en el (1,2345, 0,001) debe dar 1,235.
El problema es que RoundI (1.275, 0.01) devuelve 1.27, en lugar de 1.28. Esto se debe a que al ejecutar double valIntvRatio = val/intv, es decir, double valIntvRatio = 1.275/0.01, da 0.12749999999999. Sé que este es un problema con la doble representación en cualquier lenguaje de programación. Mi pregunta es, ¿existe un código estándar para hacer cosas como esta, sin la necesidad de preocuparse por la precisión en doble? Aquí configuro el tolerante a 1e-14, pero esto es demasiado restringido para este problema y no sé cuál es la tolerancia correcta que se debe establecer. Gracias por cualquier ayuda.
Quizás debería considerar utilizar el tipo de datos Decimal. – Kibbee
¿Por qué la ronda (100,3) daría 99? Si está redondeando a la misma posición fraccionaria que 3 (0 lugares), obtendría 100, no 99. – paxdiablo
paxdiablo: lo siento, el propósito de RoundI no es redondear para redondear el primer parámetro a la misma posición fraccionaria como el segundo parámetro. El segundo parámetro es el intervalo de ronda y el redondeo redondea el primer parámetro al valor de armario que tiene el modo 0 con respecto al segundo parámetro. – Steve