*
The moose likes Java in General and the fly likes Round a decimal to upper integer Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Round a decimal to upper integer" Watch "Round a decimal to upper integer" New topic
Author

Round a decimal to upper integer

Purushotham Kudva
Greenhorn

Joined: Mar 22, 2012
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

Joined: Oct 01, 2001
Posts: 2849
    
  11



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

Bill Johnston
Ranch Hand

Joined: Nov 17, 2005
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:


~Bill
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Oct 01, 2001
Posts: 2849
    
  11

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

Joined: May 03, 2008
Posts: 4530
    
    5

No, that' rounding half up.


luck, db
There are no new questions, but there may be new answers.
Bill Johnston
Ranch Hand

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Jan 03, 2004
Posts: 6109
    
    6

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

Joined: Oct 01, 2001
Posts: 2849
    
  11

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

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Mar 22, 2012
Posts: 7
Thank you guys... I shall try these and revert.
dennis deems
Ranch Hand

Joined: Mar 12, 2011
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

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
"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

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
OK, fair enough. Try running this:

Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

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

Joined: Nov 17, 2005
Posts: 201
Mike Simmons wrote:OK, fair enough. Try running this:


You are absolutely right. I see where I was wrong.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
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

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
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

Joined: Nov 17, 2005
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

Joined: Mar 05, 2008
Posts: 3012
    
  10
True.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Round a decimal to upper integer