Jump to content

Rounding Errors

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
7 replies to this topic

#1
chili5

chili5

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 7,247 posts
Hi everyone:

On my last contest - we had this problem: iProfits. My team and I found out a solution for this but on one of the cases we get the wrong answer.

What we end up doing is dividing by 0.693. This gives us a number and then to round to the nearest 1000 we add 1000 and then take away the remainder when dividing by 1000 (if the number is not already divisible by 10).

This works nicely but in one case we get a really screwed up answer like:

Quote

2000.0000000000002


Which is not divisible by 1000, so we add 1000 and then subtract the remainder. Giving us the output of 3000 instead of the correct output of 2000.

Does anybody have any thoughts on how to get around this weird problem?

#2
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Don't you know to never do any financial calculations with floating point numbers? :D It's actually because of JUST this problem, when doing long strings of mathematics (especially division), float point values start having alterations that could lead to the computer accidentally adding or removing pennies that shouldn't be added/removed!

The way to rectify this is to stop using float point numbers. Instead your calculations should be based on using long ints that hold the smallest division of your local currency, then performing math on them.
Wow I changed my sig!

#3
Hignar

Hignar

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 420 posts
Because you are rounding by 1000's decimals are largely irrelevant.You can get away with casting your answer as an int and finding the quotient and remainder when divided by 1000. If your remainder is less than 500 you leave the rounding as 1000 * the quotient and if the remainder is greater than or equal to 500 you add 1 to the quotient and then multiply by 1000.

I think your rounding algorithm is more flawed than you realise. By your logic we would round 2200 by adding 1000 to give 3200 and subtract the remainder of 200 meaning 2200 would round to 3000 rather than 2000.
If there's a new way, I'll be the first in line.

But, it better work this time.

#4
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Tsk Tsk Hignar...

Quote

Given that you have an idea of how much profit you want to make off your hard work, at least how many 1000s of copies must be sold? (That is, the answer is rounded to the next 1000).
That's what chili5 is supposed to do. :P Also what if chili's algorithm, accepting float point values, instead of floating up floats down, so instead of 2000.0000000000002, chili ends up with 1999.9999999999998? Then cutting off the decimal values (casting to int) brings it to 1999.
Wow I changed my sig!

#5
Hignar

Hignar

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 420 posts

ZekeDragon said:

Tsk Tsk Hignar...

That's what chili5 is supposed to do. :P Also what if chili's algorithm, accepting float point values, instead of floating up floats down, so instead of 2000.0000000000002, chili ends up with 1999.9999999999998? Then cutting off the decimal values (casting to int) brings it to 1999.

Must admit I didn't read the problem he was set. I just read in his post that he should be rounding to the nearest 1000 not to the next 1000.

I accept that my method would yield the worng result at times (although it would still correctly round both 2000.00000002 and 1999.999999 to 2000).

Appologies, chili.
If there's a new way, I'll be the first in line.

But, it better work this time.

#6
chili5

chili5

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 7,247 posts

ZekeDragon said:

Don't you know to never do any financial calculations with floating point numbers? :D It's actually because of JUST this problem, when doing long strings of mathematics (especially division), float point values start having alterations that could lead to the computer accidentally adding or removing pennies that shouldn't be added/removed!

That could be disastrous. :O What if that happened in a bank program?

Quote

The way to rectify this is to stop using float point numbers. Instead your calculations should be based on using long ints that hold the smallest division of your local currency, then performing math on them.

So instead maintain an int for dollars and an int for cents? That would work in a currency situation.

Anyways, I came up with something. If I truncate to an integer before doing the rounding, I get the correct results.

So instead of:

while (fin.hasNext()) {
            dN = fin.nextDouble();
            dSales = dN / 0.693;

            if (dSales % 1000 != 0) {
                dSales += 1000;
                
                dSales -= dSales % 1000;
            }


            System.out.println((int)dSales);
}

I have this:

while (fin.hasNext()) {
            dN = fin.nextDouble();
            dSales = dN / 0.693;

            dSales = (int)dSales;

            if (dSales % 1000 != 0) {
                dSales += 1000;
                
                dSales -= dSales % 1000;
            }


            System.out.println((int)dSales);
        }

That works better. :) Thanks everyone!!!

#7
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts

chili5 said:

So instead maintain an int for dollars and an int for cents? That would work in a currency situation.
Well I was thinking more along the lines of using a currency class that maintained a long int with just the number of cents. For every 100 cents, the representation of that Currency class would show a dollar. So if in the currency class you had 200000 cents, the toString() method would print out "2000.00". Your solution is quick and dirty, but I think it'll work for the code you have so far.
Wow I changed my sig!

#8
chili5

chili5

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 7,247 posts
Okay cool. Just so you know in this problem I wasn't actually calculating currency. I needed to find how many copies I needed to make P profit. Either way, thanks a bunch. :)