Win a copy of Penetration Testing Basics this week in the Security forum!

# Round a decimal to upper integer

Purushotham Kudva
Greenhorn
Posts: 7
Hi I need info on how to round a decimal to its upper integer.

this is the part of my code
strTotalPages = Integer.toString(noOfRec / intFetchSize)

for example say

noOfRec =22
and intFetchSize= 15

22/15 must give me 2
strTotalPages should be 2.

please help

Greg Charles
Sheriff
Posts: 2993
12

If you want to avoid floating point arithmetic I think this will work:

Bill Johnston
Ranch Hand
Posts: 201
Purushotham Kudva wrote:Hi I need info on how to round a decimal to its upper integer.

this is the part of my code
strTotalPages = Integer.toString(noOfRec / intFetchSize)

for example say

noOfRec =22
and intFetchSize= 15

22/15 must give me 2
strTotalPages should be 2.

please help

I would just do this:

Mike Simmons
Ranch Hand
Posts: 3090
14
Bill, it looks like you're trying to round to the closest integer. In the original example, 22/15 is supposed to "round" to 2 - which suggests it's rounding up, always. Not just rounding to closest digit.

Also, your rounding won't work because the a/b part is performed using ints, and loses any decimal point. You need to convert one of those to a floating-point before the division is performed, or it won't work.

Greg Charles
Sheriff
Posts: 2993
12
Bill's adding 0.5, so that would always round up, wouldn't it? I mean, it would except for the a/b truncation issue.

Darryl Burke
Bartender
Posts: 5148
11
No, that' rounding half up.

Bill Johnston
Ranch Hand
Posts: 201
Darryl Burke wrote:No, that' rounding half up.

I guess I misunderstood the request. My thinking was, since Math.round only takes float or double, the expression 22/15 is promoted and the result is ~1.467. Math.round adds .05 to that and then takes the floor of the result. The floor of 1.967 is 1.0.

Adding .5 to 1.967 makes it 2.467. The floor of that is 2. If you run the code that is what you should get. I didn't think the OP wanted to see 1 if the answer were > 1.

However, I see that the code won't work if the number is exactly 1.0, 2.0, 3.0, etc, because it will add +1, effectively making 2.0 (2) 3.0 (3);

I believe this code would work:

Or do I still misunderstand?

Mike Simmons
Ranch Hand
Posts: 3090
14
Bill Johnston wrote:My thinking was, since Math.round only takes float or double, the expression 22/15 is promoted and the result is ~1.467.

No - the problem is the order of operations. The integer division is performed first, so 22/15 = 1, and then the result of that is promoted to double. Unfortunately 1 just becomes 1.0; it can't recover the lost decimal part.

Bill Johnston wrote:I believe this code would work:

Yes, and that's basically equivalent to what Greg posted. Except Greg forgot a final cast to int, and he used a different (more direct?) way to convert the ints to doubles before the division.

Jeff Verdegan
Bartender
Posts: 6109
6
• 2
If we're starting in int and ending in int, I'd just skip all the floating point fiddle-faddle do it as

For example:

Greg Charles
Sheriff
Posts: 2993
12
Mike Simmons wrote:Except Greg forgot a final cast to int ...

I forgot that Math.ceil() returns a double, and I'll probably forget it again because it makes no sense!

Darryl Burke wrote:No, that' rounding half up.

Huh? I can't tell if that's a joke or not. In any case, I do see now it wouldn't work quite the same way as Math.ceil().
Eg.
(long)Math.ceil(1.0) = 1
Math.round(1.0 + 0.5) = 2

Mike Simmons
Ranch Hand
Posts: 3090
14
Greg Charles wrote:
Mike Simmons wrote:Except Greg forgot a final cast to int ...

I forgot that Math.ceil() returns a double, and I'll probably forget it again because it makes no sense!

Agreed.

Greg Charles wrote:
Darryl Burke wrote:No, that' rounding half up.

Huh? I can't tell if that's a joke or not.

I think not - I agree with Darryl. The norm for Java ints is to truncate, which I would call rounding down (assuming we're talking positive numbers). 1/4, 2/4, and 3/4 all get rounded down to 0. By inserting a few casts and adding .5, we can get what I would call proper rounding, such as that given by Math.round(). (int)((1 + .5)/4) and (int)((1 + .5)/2) get rounded down to 0, but (int)((3 + .5)/4) gets rounded up to 1. On average, about half of all such operations result in rounding down, and the other half round up.

Purushotham Kudva
Greenhorn
Posts: 7
Thank you guys... I shall try these and revert.

dennis deems
Ranch Hand
Posts: 808
Mike Simmons wrote:The norm for Java ints is to truncate, which I would call rounding down

To me, "rounding" implies we have a choice. With integer division there is no choice; you get an integer whether you like it or not. I don't see a need to supply alternative terminology to "truncation" which exactly describes what is happening.

Bill Johnston
Ranch Hand
Posts: 201
Mike Simmons wrote:
Bill Johnston wrote:My thinking was, since Math.round only takes float or double, the expression 22/15 is promoted and the result is ~1.467.

No - the problem is the order of operations. The integer division is performed first, so 22/15 = 1, and then the result of that is promoted to double. Unfortunately 1 just becomes 1.0; it can't recover the lost decimal part.

Don't think so, Mike. Running this code:
... results in 1.0 for the first and 2.0 for the second. I am quite sure that this is because the first results is 1.967 and the second results in 2.467. Round will then take the floor of that number; 1.0 and 2.0 respectively. Which is why my first suggestion results in 2 for this calculation, but 3 if the result of a/b were exactly 2.0.

Bill Johnston wrote:I believe this code would work:

Mike Simmons wrote:Yes, and that's basically equivalent to what Greg posted. Except Greg forgot a final cast to int, and he used a different (more direct?) way to convert the ints to doubles before the division.

My bad there - It didn't register the first time I peered at what Greg posted.

Mike Simmons
Ranch Hand
Posts: 3090
14
Bill Johnston wrote:
Mike Simmons wrote:
Bill Johnston wrote:My thinking was, since Math.round only takes float or double, the expression 22/15 is promoted and the result is ~1.467.

No - the problem is the order of operations. The integer division is performed first, so 22/15 = 1, and then the result of that is promoted to double. Unfortunately 1 just becomes 1.0; it can't recover the lost decimal part.

Don't think so, Mike. Running this code:
... results in 1.0 for the first and 2.0 for the second. I am quite sure that this is because the first results is 1.967 and the second results in 2.467.

You may be quite sure, but I think that if you remove the Math.round() and print the results, you will see a different result.

Mike Simmons
Ranch Hand
Posts: 3090
14
Dennis Deems wrote:
Mike Simmons wrote:The norm for Java ints is to truncate, which I would call rounding down

To me, "rounding" implies we have a choice. With integer division there is no choice; you get an integer whether you like it or not. I don't see a need to supply alternative terminology to "truncation" which exactly describes what is happening.

Both "truncation" and "rounding" imply the result is an integer - no difference there. But precisely because there is more than one way to round, that's why it's useful to have additional modifiers like "up" and "down" to describe the type of rounding used. Especially here in a problem where we are specifically describing the differences between those techniques. I'm not the only person to think so either - the same terms are used in java.math.RoundingMode. Sure, we can just say "truncate" instead of "round down" if you like - but I think "round down" makes a nice clear contrast with the other terms like "round up" and "round half up".

Bill Johnston
Ranch Hand
Posts: 201
Mike Simmons wrote:
Bill Johnston wrote:
Mike Simmons wrote:
Bill Johnston wrote:My thinking was, since Math.round only takes float or double, the expression 22/15 is promoted and the result is ~1.467.

No - the problem is the order of operations. The integer division is performed first, so 22/15 = 1, and then the result of that is promoted to double. Unfortunately 1 just becomes 1.0; it can't recover the lost decimal part.

Don't think so, Mike. Running this code:
... results in 1.0 for the first and 2.0 for the second. I am quite sure that this is because the first results is 1.967 and the second results in 2.467.

You may be quite sure, but I think that if you remove the Math.round() and print the results, you will see a different result.

Well that's exactly my point; and why I didn't suggest NOT using round. Math.round(double) changes the values from where (a/b) would be otherwise.

Mike Simmons
Ranch Hand
Posts: 3090
14
"Exactly my point" indicates you haven't run the code to see what it shows. Because my point is that your values of 1.967 and 2.467 DO NOT OCCUR during the evaluation of

At no point during the evaluation of this expression will you encounter those values. Now you can test this using a debugger or using print statements, or you can just imagine what will happen. But I think you will get more accurate results from testing with actual code, rather than imagining.

Bill Johnston
Ranch Hand
Posts: 201
Mike Simmons wrote:"Exactly my point" indicates you haven't run the code to see what it shows. Because my point is that your values of 1.967 and 2.467 DO NOT OCCUR during the evaluation of

At no point during the evaluation of this expression will you encounter those values. Now you can test this using a debugger or using print statements, or you can just imagine what will happen. But I think you will get more accurate results from testing with actual code, rather than imagining.

I don't have a debugger, so that's out. And you can't test it, because running:
... Will obviously give you 1; whereas running:

... will give you 2. I don't know how you are going to "see" what the intermediate values are before that result - if you know please show me.

As to imagining ... I am not imagining, I am drawing a conclusion as to what the API doco states Math.round(double) does. If I am wrong in the conclusion I am drawing, please point that out as well - not by say "It's wrong, run it", but by patiently explaining it.

And as to running the code - I did run ALL the code I posted, as well as what Greg posted.

Mike Simmons
Ranch Hand
Posts: 3090
14
OK, fair enough. Try running this:

Martin Vajsar
Sheriff
Posts: 3752
62
Purushotham Kudva wrote:Thank you guys... I shall try these and revert.

Purushotham, make sure you don't miss Jeff's response in this busy discussion: this one. It's probably the best one for your needs.

Bill Johnston
Ranch Hand
Posts: 201
Mike Simmons wrote:OK, fair enough. Try running this:

You are absolutely right. I see where I was wrong.

Jeff Verdegan
Bartender
Posts: 6109
6
Bill Johnston wrote:
I don't have a debugger, so that's out.

I bet you do. The JDK download includes jdb.

Bill Johnston
Ranch Hand
Posts: 201
Jeff Verdegan wrote:
Bill Johnston wrote:
I don't have a debugger, so that's out.

I bet you do. The JDK download includes jdb.

Ah, so I do - thank you.

Mike Simmons
Ranch Hand
Posts: 3090
14
Cool.

I haven't looked at jdb in ages. But I suspect that your time will be better served looking into one of the debuggers built into a popular IDE such as Eclipse or IntelliJ. These are much more user-friendly, and useful for much more than just debugging.

Bill Johnston
Ranch Hand
Posts: 201
Just to be clear, using your example ...

Mike Simmons wrote: ... Try running this:

I admitted that my premise for thinking that the intermediate values were floating point 1.467, etc was incorrect - I just wasn't thinking right. But your statment:
Also, your rounding won't work because the a/b part is performed using ints, and loses any decimal point. You need to convert one of those to a floating-point before the division is performed, or it won't work.
(Underline mine)
... isn't quite correct either; as your code demonstrates, round adds another .5, so that even though 22/15 rounds down to 1, adding two .5s to is does effectively bring it up to 2. So it does "work" in this case, though it is clearly wrong in other cases. The code is wrong, the division won't produce correct result if a fraction is indicated, but the overall statement will work for all but non-fractional results (22/22, 22/11, etc).

Mike Simmons
Ranch Hand
Posts: 3090
14
True.