Question is pretty straightforward, is there any benefit or difference? I've noticed that in C# the function returns a double without any decimal places, while in java it keeps the decimal places, but other than that the result is the same.
Here is the code I used in Java and C#, and the output:
//Java //C#
double a = 5.5; double a = 5.5;
System.out.println(Math.floor(a)); Console.WriteLine(Math.Floor(a));
System.out.println((int)a); Console.WriteLine((int)a);
//Output //Output
5.0 5
5 5
Yes, for negative numbers, this works in the opposite way.
Example (using Mono's C# interactive shell csharp
):
csharp> Math.Floor(-12.0d)
-12
csharp> Math.Floor(-12.5d)
-13
csharp> (int) -12.5
-12
(same for both Java/C#) and I guess most languages anyway.
Casting a floating-point number to an integer, is performed by throwing away the decimal part maintaining the integer part. The integer part of -12.5
is 12
. Thus negative numbers do a Math.Ceil
if converted to an int
.
Furthermore as @Matthew argues, a float
or double
can reach numbers like 1.023e23
(Avogadro's constant). Simply because the mantisse can't represent digits after the comma anymore. Numbers that are considered to be an integer anyway, but can't be represented by an int
. By performing a Math.floor
operation, nothing happens, but the value is still maintained. While conversion to an int
could result in overflow:
Example:
csharp> double ac = 1.023e23;
csharp> Math.Floor(ac);
1.023E+23
csharp> (int) ac;
0
Note: this may look far fetched, but there is thus a clear difference in semantics nevertheless. A difference that tends to lead to errors anyway.
In addition, it works differently for infinite numbers and NaN:
System.out.println(Math.floor(Double.POSITIVE_INFINITY)); // Prints Infinity
System.out.println((int)Double.POSITIVE_INFINITY); // Prints 2147483647
System.out.println(Math.floor(Double.NaN)); // Prints NaN
System.out.println((int)Double.NaN); // Prints 0
But I would always use them nevertheless. Casting makes things way more unreadable. Rounding up/down/off is more some kind of (side-effect) of the cast. By using Math.Ceil/Floor/Round
it is clear what you mean.
Sometimes a cast to an integer is indeed a bit more efficient than performing a floor/ceil operation first. But a smart compiler can sometimes derive that a variable will always store a positive number and thus optimize it itself. And furthermore for most applications this will result in an insignificant performance penalty.