81

When I call Math.ceil(5.2) the return is the double 6.0. My natural inclination was to think that Math.ceil(double a) would return a long. From the documentation:

ceil(double a)

Returns the smallest (closest to negative infinity) double value that is not less than the argument and is equal to a mathematical integer.

But why return a double rather than a long when the result is an integer? I think understanding the reason behind it might help me understand Java a bit better. It also might help me figure out if I'll get myself into trouble by casting to a long, e.g. is

long b = (long)Math.ceil(a);

always what I think it should be? I fear there could be some boundary cases that are problematic.

Cœur
  • 37,241
  • 25
  • 195
  • 267
PengOne
  • 48,188
  • 17
  • 130
  • 149
  • See http://stackoverflow.com/questions/3412449/why-does-math-round-return-a-long-but-math-floor-return-a-double – starblue Sep 02 '11 at 19:32

2 Answers2

74

The range of double is greater than that of long. For example:

double x = Long.MAX_VALUE;
x = x * 1000;
x = Math.ceil(x);

What would you expect the last line to do if Math.ceil returned long?

Note that at very large values (positive or negative) the numbers end up being distributed very sparsely - so the next integer greater than integer x won't be x + 1 if you see what I mean.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I guess in your final sentence you are talking about a loose of precision but I think that does not depend on the high the number is but on the number of significant digits of it (in binary). I'll try to find an example. – aalku Sep 02 '11 at 17:35
  • @user270349: The absolute gap between consecutive double values becomes larger as the value becomes larger. The number of significant digits represented remains the same (other than for subnormal numbers). – Jon Skeet Sep 02 '11 at 17:37
  • 2
    Example: `2^60` can be represented as double while `2^60 (+/-) 1` cannot – aalku Sep 02 '11 at 17:56
  • You are right. An increment of one in the mantissa implies a much bigger number if the exponent is big, obvious. – aalku Sep 02 '11 at 17:59
  • 9
    But then why does `round` return a `long`? – Zoltán Aug 29 '14 at 13:03
  • 1
    ^ Zoltán, exactly. `Math.round` returning `long` is inconsistent with the above reasoning. – Tim Harper May 26 '16 at 00:54
14

A double can be larger than Long.MAX_VALUE. If you call Math.ceil() on such a value you would expect to return the same value. However if it returned a long, the value would be incorrect.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • the `double` values that are larger than `Long.MAX_VALUE` may not be represented exactly, so the `double` result of `ceil(big_double)` will not be `big_double + 1`. So it's still incorrect... – Ciprian Tomoiagă Mar 17 '17 at 19:31
  • @CiprianTomoiaga you are right that it won't be big_double +1 as this would be big_double. Any value which is too large to be represented as a `long` has no fractional part. – Peter Lawrey Mar 19 '17 at 15:07