39

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?

Robin Rodricks
  • 99,791
  • 133
  • 372
  • 575

3 Answers3

35

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.

Trilarion
  • 9,318
  • 9
  • 55
  • 91
Alvin Wong
  • 11,512
  • 5
  • 44
  • 73
  • 3
    Note, 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
13

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.

Habib
  • 205,061
  • 27
  • 376
  • 407
  • 2
    +1 Indeed, since not all times we need to round to an int – V4Vendetta Feb 08 '13 at 05:42
  • 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
  • @Habib Right, thanks, I didn't see the last part for some reason – PandaWood Oct 21 '15 at 06:23
2

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.

Igoy
  • 2,592
  • 18
  • 22