Math.ceil() will always round up, however you are doing integer division with 3/2. Thus, since in integer division 3/2 = 1 (not 1.5) the ceiling of 1 is 1.
What you would need to do to achieve the results you want is Math.ceil(3/2.0);
By doing the division by a double amount (2.0), you end up doing floating point division instead of integer division. Thus 3/2.0 = 1.5, and the ceil() of 1.5 is always 2.
Math.ceil() will always round up, however you are doing integer division with 3/2. Thus, since in integer division 3/2 = 1 (not 1.5) the ceiling of 1 is 1.
What you would need to do to achieve the results you want is Math.ceil(3/2.0);
By doing the division by a double amount (2.0), you end up doing floating point division instead of integer division. Thus 3/2.0 = 1.5, and the ceil() of 1.5 is always 2.
A bit of black magic, and you can do it all with integers:
// Divide x by n rounding up
int res = (x+n-1)/n
You are doing 157/32 which is dividing two integers with each other, which always result in a rounded down integer. Therefore the (int) Math.ceil(...) isn't doing anything. There are three possible solutions to achieve what you want. I recommend using either option 1 or option 2. Please do NOT use option 0.
Option 0
Convert a and b to a double, and you can use the division and Math.ceil as you wanted it to work. However I strongly discourage the use of this approach, because double division can be imprecise. To read more about imprecision of doubles see this question.
int n = (int) Math.ceil((double) a / b));
Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
You do a / b with always floor if a and b are both integers. Then you have an inline if-statement which checks whether or not you should ceil instead of floor. So +1 or +0, if there is a remainder with the division you need +1. a % b == 0 checks for the remainder.
Option 2
This option is very short, but maybe for some less intuitive. I think this less intuitive approach would be faster than the double division and comparison approach:
Please note that this doesn't work for b < 0.
int n = (a + b - 1) / b;
To reduce the chance of overflow you could use the following. However please note that it doesn't work for a = 0 and b < 1.
int n = (a - 1) / b + 1;
Explanation behind the "less intuitive approach"
Since dividing two integers in Java (and most other programming languages) will always floor the result. So:
int a, b;
int result = a/b (is the same as floor(a/b) )
But we don't want floor(a/b), but ceil(a/b), and using the definitions and plots from Wikipedia: 
With these plots of the floor and ceil functions, you can see the relationship.

You can see that floor(x) <= ceil(x). We need floor(x + s) = ceil(x). So we need to find s. If we take 1/2 <= s < 1 it will be just right (try some numbers and you will see it does, I find it hard myself to prove this). And 1/2 <= (b-1) / b < 1, so
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
This is not a real proof, but I hope you're satisfied with it. If someone can explain it better I would appreciate it too. Maybe ask it on MathOverflow.
157/32 is int/int, which results in an int.
Try using the double literal - 157/32d, which is int/double, which results in a double.
Math.ceil() will do the work.
But, your assumption that 91 / 8 is 11.375 is wrong.
In java, integer division returns the integer value of the division (11 in your case).
In order to get the float value, you need to cast (or add .0) to one of the arguments:
float chunkSize = 91 / 8.0 ;
Math.ceil(chunkSize); // will return 12!
ceil is supposed to do just that. I quote:
Returns the smallest (closest to negative infinity) double value that is greater than or equal to the argument and is equal to a mathematical integer.
EDIT: (thanks to Peter Lawrey): taking another look at your code you have another problem. You store the result of integer division in a float variable: float chunkSize = 91 / 8 ; java looks at the arguments of the division and as they are both integers it performs integer division thus the result is again an integer (the result of the division rounded down). Now even if you assign this to the float chunkSize it will still be an integer(missing the double part) and ceil, round and floor will all return the same value. To avoid that add a .0 to 91: float chunkSize = 91.0 / 8;. This makes one of the arguments double precision and thus double division will be performed, returning a double result.
Ceiling
Normal integer division rounds to zero, truncating any fraction.
Instead, what you want is to round toward positive infinity, known as the ceiling.
Math.ceilDiv
In Java 18+, use Math.ceilDiv. Pass your two int values, dividend and divisor. Returns an int.
int x = 15 / 8 ; // 1
int y = Math.ceilDiv ( 15 , 8 ) // 2
Math.ceil
In earlier Java, use Math.ceil(), casting the result to int.
- This is still faster than to avoid doubles by using
abs(). - The result is correct when working with negatives, because -0.999 will be rounded UP to 0
Syntax:
(int) Math.ceil( (double) dividend / divisor );
int x = 15 / 8 ; // 1
int y = ( int ) Math.ceil ( ( double ) 15 / 8 ); // 2
To round up an integer division you can use
import static java.lang.Math.abs;
public static long roundUp(long num, long divisor) {
int sign = (num > 0 ? 1 : -1) * (divisor > 0 ? 1 : -1);
return sign * (abs(num) + abs(divisor) - 1) / abs(divisor);
}
or if both numbers are positive
public static long roundUp(long num, long divisor) {
return (num + divisor - 1) / divisor;
}
This is probably because when you divide an Integer by an Integer you get an Integer back which has the same value as Decimal.round(RoundingMode.DOWN).
system.assertEquals(1, 8/5);
system.assertEquals(8/5, (8.0/5).round(RoundingMode.DOWN);
system.assertEquals(-1, -8/5);
system.assertEquals(-8/5, (-8.0/5).round(RoundingMode.DOWN);
system.assertEquals(2, 7/3);
system.assertEquals(7/3, (7.0/3).round(RoundingMode.DOWN);
If you know you have Integers and you want to get their ceiling, you could do something like:
public static Integer ceiling(Integer x, Integer y)
{
return Math.ceil(Decimal.valueOf(x).divide(y, /*digits*/ 1));
}
Integer Division
In Apex Code, similar to Java, when there are two like numeric data types (e.g. both Integers), then they are calculated in a way that returns the same data type. Integers cannot store fractions, so when you do something like 7/3, the fraction is silently discarded. As far as I know, integer division works in the same for every programming language in the world where the result of integer arithmetic is an integer.In many languages where the result of two integers being divided together results in an integer, the fraction is often dropped entirely, although exceptions do exist (some perform rounding, instead).
Parameter Promotion
You'll notice that there's no function Math.ceil that accepts an Integer. This means if you give it an integer, it will implicitly be cast to a floating point value before being processed by Math.ceil.
Arithmetic Promotion
When two numbers are operated on using the standard operators (+, -, /, *), if one of those parameters are a floating point value, the other one will also automatically become a floating point value. Similarly, if a integer and a long were involved in an operation, both numbers become long, and the return type becomes long. So, the goal is to create a situation where a floating point is returned. For example, this results in the correct result:
Integer x = Math.ceil(7.0/3).intValue();
Here, the 7.0 indicates a floating point operation. You'd also get the same effect if you did this:
Decimal x = 7;
Integer y = 3;
Integer z = Math.ceil(x/y).intValue();
This behavior is well-defined, and mimics the behavior in Java. You can read more about automatic widening conversion in the Java documentation, as well as rules about integer division. You'll find that, while not explicitly mentioned in the Apex Code Developer's Guide (as far as I can tell), it obeys the same rules.
is clayneeded an int/long? if you're doing int/long division, it'll truncate any fractional component before it gets to the Math.ceil. Given the size of your inputs, I'd stay away from floats/doubles, and use BigDecimals to do the math accurately here.
Looks like clayneeded has integer type (probably long). So clayneeded/7500000000L is integer division (quotient), thus ceil computes the ceiling of an integer, so itself.
So you can compute it like this (if the remainder of the integer division is not nul then the ceiling must produce the next integer) :
long remainder = clayneeded % 7500000000L;
long result = (clayneeded/7500000000L)+(remainder!=0?1:0);