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:

~Bill

*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.

Darryl Burke wrote:No, that' rounding

halfup.

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?

~Bill

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.

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

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.

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.

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

beforethe division.

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

~Bill

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.

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".

Mike Simmons wrote:

Bill Johnston wrote:

Mike Simmons wrote:

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.

~Bill

*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.

Mike Simmons wrote:"Exactly my point" indicates you haven't run the code to see what it shows. Because

mypoint 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 justimaginewhat 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.

~Bill

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.

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:

(Underline mine)

Also, your rounding won't workbecause 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.

... 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).

~Bill

It is sorta covered in the JavaRanch Style Guide. |