¿Por qué Math.Floor (Double) devuelve un valor de tipo Double?


103

Necesito obtener el valor entero del lado izquierdo de un decimal o doble. Por ejemplo: necesito obtener el valor 4 de 4.6. Intenté usar la función Math.Floor pero devuelve un valor doble, por ejemplo: devuelve 4.0 de 4.6. La documentación de MSDN dice que devuelve un valor entero. ¿Me estoy perdiendo de algo? ¿O hay una forma diferente de lograr lo que estoy buscando?


2
La documentación de MSDN dice que devuelve un valor entero . La documentación de MSDN indica que Math.Floor devuelve System.Double, no integer.
banda ancha

Un valor entero es efectivamente necesario, pero no significa que pueda almacenarse en un "int" o "long". Un "doble" almacena con éxito todos los valores enteros en un rango mucho más amplio que solo "int" Tenga en cuenta que algunos valores enteros se pueden redondear cuando la parte de la mantisa no tiene suficientes bits para almacenar todos los dígitos del valor entero, cuando su exponente en base 2 va por encima de 52: este redondeo de valores enteros en "doble" puede ocurrir para enteros por encima de 2 ^ 52 o por debajo de -2 ^ 52 pero el resultado seguirá siendo el entero más cercano representable; si usa "(largo) Piso (x)", la conversión podría ser en gran medida incorrecta.
verdy_p

Sin embargo, tenga en cuenta que el rango válido de valores enteros que se pueden representar en un "doble" es extremadamente grande, con valores absolutos hasta: (1 + (1 - 2 ^ −52)) × 2 ^ 1023 ≈ 1.7976931348623157E308; es mucho más de 2 ^ 63-1 con "long". Sin embargo, el rango de enteros que se pueden almacenar de forma distinta es más restringido, porque un "doble" solo tiene 52 bits para la mantisa (más 1 bit implícito para el bit más significativo, no almacenado), lo que significa que "doble" solo puede almacenar enteros exactamente solo cuando su valor absoluto es inferior a 2 ^ 53.
verdy_p

Desafortunadamente, Math.Floor () no devuelve un tipo de variable "Número" utilizando internamente "Long" si es posible, o "Double" de lo contrario solo para enteros grandes redondeados. Y la biblioteca matemática estándar no maneja ese tipo de número de variable unificado. Existen otras bibliotecas matemáticas que implementan un tipo de número unificado, incluidos enteros largos, dobles o grandes codificados en decimal o binario empaquetado sin pérdida de rango o precisión admitidos.
verdy_p

Respuestas:


146

El rango de doublees mucho más amplio que el rango de into long. Considere este código:

double d = 100000000000000000000d;
long x = Math.Floor(d); // Invalid in reality

El número entero está fuera del rango de long, entonces, ¿qué esperaría que sucediera?

Normalmente, usted sabe que el valor será realmente estar dentro del rango de into long, por lo que lo lanzas:

double d = 1000.1234d;
int x = (int) Math.Floor(d);

pero la responsabilidad de ese reparto recae en el desarrollador, no en Math.Floorsí mismo. Habría sido innecesariamente restrictivo hacer que fallara con una excepción para todos los valores fuera del rango de long.


2
Floor devuelve una representación entera de double, y devuelve double para cálculos científicos, esta respuesta no es correcta porque double tiene 64 bits y long también tiene 64 bits, pero double no puede almacenar dígitos exactos de bits significativos más bajos incluso si se puede almacenar correctamente en largo.
Akash Kava

1
@Jon: ¿cómo es que no ha intervenido en el debate sobre cómo hacer que un número positivo sea negativo en C # ?: stackoverflow.com/questions/1348080/…
MusiGenesis

3
@Jon: tómate tu tiempo. Resulta que la comunidad descubrió que multiplicar un número positivo por -1 lo hará negativo. Todo está bien en StackOverflow.
MusiGenesis

1
@javapowered: No, (int) 15.0 no es 0. Algo más ha ido mal, pero no podemos decir qué de eso. Cree un programa breve pero completo que demuestre esto y luego haga una pregunta. Sospecho que le resultará difícil reproducirse ...
Jon Skeet

1
@MusiGenesis: <code> (int) IGNORE_RATIO * Volume </code> se calcula como <code> (int) 0.15 * Volume </code>, pero el encasillado se aplica solo a la proporción, no al resultado del producto, y obtienes <code> 0 * Volume </code> es decir, ¡cero! Use <code> (int) (IGNORE_RATIO * Volume) </code> en su lugar para resolver SU error.
verdy_p

11

Según MSDN, Math.Floor (double) devuelve un doble: http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

Si lo quieres como int:

int result = (int)Math.Floor(yourVariable);

Puedo ver cómo el artículo de MSDN puede ser engañoso, deberían haber especificado que si bien el resultado es un "entero" (en este caso, significa un número entero), todavía es de TYPE Double


Gracias por su respuesta. En realidad, estaba viendo este artículo: msdn.microsoft.com/en-us/library/e0b5f0xb.aspx Pero de todos modos, probaré tu sugerencia. Gracias.

Bueno, es cierto, dice en la parte superior "devuelve un número entero", pero el tipo se especifica debajo: public static double Floor (doble d)
Neil N

3
integer! = int( answers.com/integer ): los enteros se pueden almacenar en Double(ver la respuesta de Jon), y hay un número infinito de enteros que no se pueden almacenar en un int.
Shog9

Shog, no dije que no pudieran. Lo que dije fue "todavía es de TYPE Double"
Neil N

1
@Neil: correcto - solo quería enfatizar la diferencia entre "entero" (nombre de un conjunto) y int(nombre de un tipo).
Shog9

4

Si solo necesita la parte entera de un número, conviértalo en un int. Esto truncará el número en el punto decimal.

double myDouble = 4.6;
int myInteger = (int)myDouble;

2
Es importante tener en cuenta que la conversión a se intcomporta de manera diferente a Floor, para números negativos. Floorsiempre se truncará al número más negativo, mientras que la conversión a intse truncará hacia 0.
Magnus


0

Floor lo deja como doble para que pueda hacer más cálculos dobles con él. Si lo quieres como int, lanza el resultado de floor como int. No emita el doble original como un int porque las reglas para el piso son diferentes (IIRC) para los números negativos.


0
Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))

Esto le dará el valor exacto lo que quiere como si se toma 4.6devuelve 4como salida.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.