2010-08-14 11 views

Respuesta

27

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

(Source)

+0

Dijeron o de largo en la pregunta. – bwawok

+3

El punto sigue siendo el mismo.Un "doble" puede ser más grande que 9223372036854775807. – dan04

+1

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

-2

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 ...

+2

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

+3

-1 - Sé * cómo *, me pregunto * por qué *. Tu respuesta ni siquiera tiene sentido. – TheCloudlessSky

8

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.

2

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.

+0

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

+0

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

Cuestiones relacionadas