In C#, why don't the rounding math functions Floor, Ceiling and Round return an int
? Considering the result of the function will always be an integer, why does it return a float
, double
or decimal
?

- 110,798
- 141
- 398
- 607
-
1Round is overloaded, and the return types have to match for starters ;p – leppie Feb 08 '13 at 05:17
-
13Imagine you call `Math.Round(1E30)` and it returns an `int`, what will happen? – Alvin Wong Feb 08 '13 at 05:18
-
So you're saying it's the BCL's job to determine what you want the result to be? – Simon Whitehead Feb 08 '13 at 05:18
-
3It makes sense for `Math.Round()` to return the same type as its argument. A better question would be why there aren't functions for `Math.RoundToInt32` or `Math.RoundToInt64`, `Math.FloorToInt32`, and `Math.FloorToInt64`. – supercat Aug 16 '13 at 21:34
-
Performance and stability. – aj.toulan Apr 09 '14 at 14:59
3 Answers
double
has the range of ±5.0 × 10−324 to ±1.7 × 10308 and long
has the range of –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Unfortunately not all integral floating point values can be represented by an integer.
For example, 1e19
has already exceeded the range of a 64-bit signed integer.
(long)Math.Round(1e19) == -9223372036854775808L // WTF?
While it is true that the single-argument overloads Math.Round(double)
and Math.Round(decimal)
will always return an integral value, these overloads still cannot return an integer value type.
If you know that the value passed to the function will return a value representable by an integer value type, you can cast it yourself. The library won't do that because it needs to consider the general case.

- 10,591
- 9
- 64
- 104

- 12,210
- 5
- 51
- 77
-
3Note, however, that there are long integers which are *not* representable as doubles: `(double)100000000000000001L == 1e17` (and `1e17 == 1e17+1`). – Antal Spector-Zabusky Feb 09 '13 at 02:55
-
@AntalS-Z yep. For greater preceision, using [`decimal`](http://msdn.microsoft.com/en-us/library/364x0z75(v=vs.80).aspx) type is better. – Alvin Wong Feb 09 '13 at 03:18
Considering the result of the function will always be an integer,
No it won't be. You can even specify number of digits with Math.Round Method (Double, Int32)
digits Type:
System.Int32
The number of fractional digits in the return value.

- 219,104
- 29
- 407
- 436
-
2
-
I can't help but be dumb here, the documentation for Round says "returns the integer nearest a" - and you're saying it doesn't always return an integer. This doesn't seem to make sense. – PandaWood Oct 20 '15 at 04:27
-
@PandaWood, where do you see "returns the integer nearest" ? I couldn't find it, could you please share the link. If you are referring to this `The integer nearest a. If the fractional component of a is halfway between two integers, one of which is even and the other odd, then the even number is returned. Note that this method returns a Double instead of an integral type.` then note the last part. – Habib Oct 20 '15 at 13:24
-
This is done to include numbers larger than what are included in the range of an int. So Math.Floor will return a double which could be casted to int or long based on the size and developer. If you tried Math.Floor outside range of int, it'd have failed if Math.Floor returned an int, but it doesn't, it returns a double which you can cast to long.
double d = 4147483647.5678;
long a = (long)Math.Floor(d);
int b = (int)Math.Floor(d);
Console.WriteLine(a);
Console.WriteLine(b);
Note that on casting to int, b was pushed back to MIN int, since int can't accomodate it.

- 2,942
- 22
- 23