Bueno, hoy he tenido un problemilla bastante estúpido de redonde con c# al intentar redondear un número doble a entero. El tema era el siguiente.
Se precisa obtener un número como 155.045 y quitarle 2 decimales, por lo que se multiplica por 100 quedando 15504.5. Pero necesitamos converto esto en un entero y que nos quede 15505 como total. Bien lo lógico es usar simplemente
double num1 = 155.045;
double calculo = num1 * 100;
int redondeado = Converto.ToInt32(calculo);
Console.WriteLine(redondeado);
Y en mi caso esto me estaba devolviendo un valor 15504. Es decir, no estaba haciendo correctamente el redondeo.
Tras unas primeras investigaciones de porqué estaba pasando ésto, encontré que se podría utilizar el metodo Math.Round(), pero en la práctica me retornaba el mismo valor que cuando intentaba convertir a int directamente. Entonces intenté forzar un poco el redondeo con las opciones de éste método utilizando Math.Rount(calculo, MidpointRounding.AwayFromZero), pero obtuve el mismo resultado.
Si leen la documentación de los enlaces, podréis comprobar que se suponer que debería de hacerlo correctamente, pero en la práctica no es así. Pensé que sería un problema de la localización, e intenté frozar a utlizar "en-AU", ya que en mi caso estoy en Australia, pero seguía con el mismo problema.
La solución
Finalmente la solución vino de manos de un prueba un poco estúpida. Intenté sumar 0.001 a entero, quedando como 155.0451 * 100 y me redondeó correctamente a 15505. Pero claro. Esto conllevaba un riesgo, y es que cuando fuera algo como 155.0449 me convertiría a 155.0450 y por lo tanto el redondeo de nuevo no sería el correcto, ya que yo necesito el número 155.044 para convertir como 15504. ¿Qué podríamos hacer en este caso? Finalmente lo que hice fué sumar 10 posiciones decimales más. Es decir, convertir a entero un numero como 155.0450000001, de ésta forma lo redondeaba correctamente a 15505. Y cuando era 155.0440000001 lo redondeaba a 15504 correctamente.
double num1 = 155.045;
double calculo = (num1 * 100) + 0.0000000001;
int redondeado = Converto.ToInt32(calculo);
Console.WriteLine(redondeado);
Conclusion
Se que no es la mejor solución, pero funciona. El problema creo qeu viene deribado de cómo se hace el redondeo. Cuando hablamos de dinero, como era el caso aunque no lo comenté antes, nos interesa no perder céntimos y si es 0.045 que redondee hacia arriba (0.05), y cuando es 0.044 que redondee hacia abajo (0.04). Esto es lo mismo que hacen los banco para robarnos dinero en cada transacción.
Espero que haya sido de ayuda para todos.
Happy coding.
#csharp #errores