Cada vez que uso Math.Round/Floor/Ceiling
Siempre echo a int
(o quizás long
si es necesario). ¿Por qué exactamente devuelven double
si siempre devuelve un número entero?¿Por qué Math.Round/Floor/Ceiling no devuelve long o int?
Respuesta
El resultado puede no ajustarse en un int (o un largo). El rango de un doble es mucho mayor.
rango aproximado de doble: ± 5.0 × 10 -324 a ± 1,7 × 10
No hay ninguna razón dada en los documentos que he podido encontrar. Mi mejor opción es que si trabajas con dobles, es probable que quieras que las operaciones en dobles devuelvan el doble. Redondearlo para lanzar a un int fue considerado por el diseñador del lenguaje menos común que redondear y mantener como un doble.
Se puede escribir su propio método que echó a un int para usted en alrededor de 2 líneas de código, y mucho menos trabajo que enviar una pregunta a desbordamiento de pila ...
Claro que es trivial escribir el tuyo, pero la respuesta de Mark proporciona una idea. StackOverflow no siempre se trata del "cómo", también me gusta el "por qué" :) – si618
-1 - Sé * cómo *, me pregunto * por qué *. Tu respuesta ni siquiera tiene sentido. – TheCloudlessSky
Estoy de acuerdo con la respuesta de que la marca Es posible que el resultado no encaje en un long
, pero podría preguntarse: ¿y si C# tuviera un tipo de long
mucho más largo? Bueno, esto es lo que sucede en Python, con sus números enteros de longitud arbitraria:
>>> round(1.23e45)
1229999999999999973814869011019624571608236032
La mayoría de los dígitos son el "ruido" de la coma flotante error de redondeo. Tal vez parte de la motivación para Round
/Floor
/Ceiling
al devolver double
en C# era para evitar la ilusión de una precisión falsa.
Una explicación alternativa es que el módulo .NET Math
utiliza un código escrito en C, en el que floor y ceil devuelven tipos de punto flotante.
Al margen de los argumentos, ninguna de estas respuestas aborda lo que, para mí, es un problema fundamental al devolver un número de punto flotante cuando realmente se desea un número entero exacto. Me parece que el número de coma flotante calculado podría ser menor o mayor que el entero deseado por un pequeño error de redondeo, por lo que la operación de lanzamiento podría crear un error de apagado por uno. Yo pensaría que, en lugar de lanzar, necesitas aplicar una función redonda más cercana entera (no doble) al doble resultado de floor()
. O bien escribe tu propio código. Las versiones de la biblioteca C de floor()
y ceil()
son muy lentas de todos modos.
¿Es esto cierto o me falta algo? Hay algo sobre una representación exacta de enteros en un estándar de punto flotante IEEE, pero no estoy seguro de si esto hace que el yeso sea seguro o no.
Preferiría que el rango compruebe la función (si es necesario para evitar el desbordamiento) y devolver una larga. Para mi propio código privado, puedo omitir la verificación de rango. He estado haciendo esto: existen
long int_floor(double x)
{
double remainder;
long truncate;
truncate = (long) x; // rounds down if + x, up if negative x
remainder = x - truncate; // normally + for + x, - for - x
//....Adjust down (toward -infinity) for negative x, negative remainder
if (remainder < 0 && x < 0)
return truncate - 1;
else
return truncate;
}
contrapartes para ceil()
y round()
con diferentes consideraciones para los números negativos y positivos.
Si lo que se quiere es asignar valores de punto flotante a las cosas que se pueden dar al código que requiere 'Int32' o' Int64', que tienen métodos para realizar dicha asignación directamente usando round-to-nearest-even o round-towards -negativo-infinito sería útil. – supercat
Una operación de redondear a entero en flotantes no puede crear un error de redondeo que no existía actualmente, ya que el entero por encima del número más grande con una parte fraccionaria es representable con precisión. – supercat
- 1. ¿Por qué Int64.MaxValue devuelve un Long?
- 2. impresión unsigned long long int Tipo Valor Devuelve resultados extraños
- 3. por qué math.Ceiling (double a) no devuelve int directamente?
- 4. C++: long long int vs. long int vs. int64_t
- 5. ¿Por qué (int) (33.46639 * 1000000) devuelve 33466389?
- 6. ¿Está `int` por defecto` signed long int` en C++?
- 7. 'long long int' se interpreta como 'long int'. ¿Cómo puedo evitar esto?
- 8. ¿GCC es compatible con long long int?
- 9. long int en PHP
- 10. javax.servlet.HttpServletRequest.getContentLength() devuelve int solo
- 11. double double vs long int
- 12. Por qué lanzar/convertir de int devuelve un asterisco
- 13. ¿Puedo convertir long a int?
- 14. ¿Qué sucede si main() no devuelve un valor int?
- 15. ¿Por qué main no devuelve 0 aquí?
- 16. ¿Hay tipos más grandes que long long int en C++?
- 17. ¿Por qué el calendario de Java establecido (int year, int month, int date) no devuelve la fecha correcta?
- 18. ¿Por qué AdMob devuelve NO FILL
- 19. ¿Por qué readf no devuelve un valor?
- 20. ¿Por qué este código NO devuelve NullPointerException?
- 21. Tipo de clave principal: int vs long
- 22. Cómo convertir long a int en .net?
- 23. ¿Diferencia entre long e int en C#?
- 24. devuelve un int o pasa un puntero int - ¿Qué es mejor?
- 25. Enumerable.Cast <T> método de extensión falla al lanzar desde int a long, ¿por qué?
- 26. getCheckedRadioButtonId() devuelve inútil int?
- 27. ¿Cómo se maneja Python int y long?
- 28. Convierte long to two int y viceversa
- 29. ¿Por qué column = NULL no devuelve filas?
- 30. ¿por qué esta función no devuelve decimal?
Dijeron o de largo en la pregunta. – bwawok
El punto sigue siendo el mismo.Un "doble" puede ser más grande que 9223372036854775807. – dan04
Pensé que esta sería la razón, pero solo quería asegurarme. Obviamente, redondear a un número * más grande * que un largo es raro para * la mayoría de las aplicaciones *, Microsoft todavía tenía que implementarlo para que tenga sentido matemáticamente. ¡Gracias! – TheCloudlessSky