views:

5817

answers:

10

Okay, here's my problem. Basically I have this problem.

I have a number like .53999999. How do I round it up to 54 without using any of the Math functions?

I'm guessing I have to multiply by 100 to scale it, then divide? Something like that?

Thanks guys!

EDIT: more info The issue is with money. let's say I have $50.5399999 I know how to get the $50, but I don't have how to get the cents. I can get the .539999 part, but I don't know how to get it to 54 cents.

+6  A: 

Why would you not want to use any Math functions?

static long round(double a)

-Returns the closest long to the argument.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html

To represent money I would take the following advice instead of re-inventing the wheel:

http://www.javapractices.com/topic/TopicAction.do?Id=13

Chris Ballance
The problem is that we have not covered anyting regarding 'static' and 'round'.The issue is with money.let's say I have $50.5399999I know how to get the $50, but I don't have how to get the cents.I can get the .539999 part, but I don't know how to get it to 54 cents.
I added a note about representing money with Java
Chris Ballance
A: 

What exactly are you trying to do? Are you always trying to go to two digits? Or are you always trying to fix things like 99999 at the end no matter what?

According to the comments, it is in fact the former: rounding to dollars and cents. So indeed just round(100*a)/100 is what you want. (The latter would be much more complicated...)

Finally, if you just want to extract the cents part, the following would work:

dollars_and_cents = round(100*a)/100
cents = (dollars_and_cents-(int)dollars_and_cents)*100

(or does java just have frac? In which case the last line would just be frac(dollars_and_cents)*100.

Andrew Jaffe
I commented on the first reply on what exactly I am trying to do."The issue is with money. let's say I have $50.5399999 I know how to get the $50, but I don't have how to get the cents. I can get the .539999 part, but I don't know how to get it to 54 cents."
+11  A: 

You should use a decimal or currency type to represent money, not floating point.

recursive
Yes, floating point currency storage can lead to very bad things after a bit of computation.
Chris Ballance
This is important! Never use floating point numbers for money! Bad things _will_ happen!
Svante
Store currency as a long (number of cents)
basszero
What about fractional cents (calculations involving percents of money may give rise to fractional cents).
Albert
@Albert: Most currency types can handle this. Otherwise use another decimal type, or long number of 1/100 cents.
recursive
A: 

Sean seems to have it, except, if you want to impose proper rules then you may want to throw in an if statement like so:

double value = .539999;
int result = (int) (value*100);
if(((value*100)%result)>.5)
    result++;
gnomed
i wish people would comment why they downvote, i dont see how this isnt acceptable code...
gnomed
@gnomed: agreed: downvote should get a comment. It looks fine to me, so one up. only improvement would be to package this as a function with the precision passed as a param.
Clayton
thanks. a fine improvement too.
gnomed
+11  A: 

I would use something like:

BigDecimal result = new BigDecimal("50.5399999").setScale(2, BigDecimal.ROUND_HALF_UP);

There is a great article called Make cents with BigDecimal on JavaWorld that you should take a look at.

cgreeno
I liked your first response better.
Sean Bright
BigDecimal is indeed the answer
chburd
What's the trade of with the first answer?: int i = ( int ) ( x + .5 )
OscarRyz
not sure what you are asking? I changed my answer because the question was edited.
cgreeno
A: 

You need to make the number .535 and compare that with your original number to see if you'll round up or down. Here's how you get .535 from .53999999 (should work for any number):

num = .53999999;
int_num = (int)(num * 100); // cast to integer, however you do it in Java
compare_num = (int_num + 0.5) / 100;

compare_num would be .535 in this case. If num is greater than or equal to compare_num, round up to int_num + 1. Otherwise round down simply to int_num.

yjerem
Yay, a real answer! =]
strager
At those who assume "round up" means "always round up" ... This could be the case, yes. Just replace 0.5 in @Ruten's example with 0.9999999... Or, negate and round down, then negate again.
strager
+5  A: 

If 50.54 isn't representable in double precision, then rounding won't help.

If you're trying to convert 50.53999999 to a whole number of dollars and a whole number of cents, do the following:

double d = 50.539999; // or however many 9's, it doesn't matter
int dollars = (int)d;
double frac = d - dollars;
int cents = (int)((frac * 100) + 0.5);

Note that the addition of 0.5 in that last step is to round to the nearest whole number of cents. If you always want it to round up, change that to add 0.9999999 instead of 0.5.

Bill the Lizard
A: 

I suggest you use long for rounding a double value. It won't matter for small numbers but could make a difference.

double d = 50.539999;
long cents = (long)(d * 100 + 0.5);
double rounded = cents/100;
Peter Lawrey
+6  A: 

Math with money is more complex than most engineers think (over generalization)

If you are doing currency calculations, I think you may be delving into problems that seem simple at their surface but are actually quite complex. For instance, rounding methods that are a result of business logic decisions that are repeated often can drastically affect the totals of calculations.

If this is homework, showing the teacher that you have thought through the real-world problem rather than just slung a bunch of code together that "works" - will surely be more impressive.

On a side note, I initially was going to suggest looking at the implementation of the Java math methods in the source code, so I took a look. I noticed that Java was using native methods for its rounding methods - just like it should.

However, a look at BigDecimal shows that there is Java source available for rounding in Java. So rather than just give you the code for your homework, I suggest that you look at the BigDecimal private method doRound(MathContext mc) in the Java source.

Elijah
The Currency class doesn't actually do any formatting, nor does it store any monetary values; it's just holds a little bit of information about the properties of a currency, of which getDefaultFractionDigits() is the only really relevant one here (and duplicates information in the question anyway).
Andrzej Doyle
+1  A: 

Try storing your currency as number of cents (you could abstract this to number of base curreny units) with a long.

Edit: Since this is homework, you may not have control over the types. Consider this a lesson for future projects

long money = 5054;

long cents = money % 100;
long dollars = money / 100; // this works due to integer/long truncation

System.out.printf("$%d.%02.d", dollars, cents);
basszero