Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

Currency Rounding Up

  • 13-09-2011 8:16pm
    #1
    Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭


    Needed: Algorithm for rounding up to nearest cent.

    e.g:

    $50.001 should go to $50.01
    $50.000 should go to $50.00
    $49.999 should go to $50.00
    $49.989 should go to $49.99

    It's custom software for XML messaging.

    I have only two (useful) methods available at the moment:

    roundUp(50.xx, 1) will return 51

    decimalFormat(50, "0.00") will return 50.00;

    I also have limited operators (+, -, *, /).

    So I am doing this:

    x = 50.001

    y = ((x - 0.001) / 0.01)

    y = roundUp(y)

    y = (y * 0.01)

    y = decimalFormat(y, "0.00")

    Seems to work ok, can ye spot any problems with it?


Comments

  • Registered Users, Registered Users 2 Posts: 6,265 ✭✭✭MiCr0


    Is this homework?


  • Registered Users, Registered Users 2 Posts: 648 ✭✭✭Freddio


    if ((x * 100) modulus 10) == 0 then result = x

    else

    result = ((floor(x * 100) + 1) / 100)

    clean_result = format(result, "0.00")

    but some languages might be able to do it in one command


  • Registered Users, Registered Users 2 Posts: 648 ✭✭✭Freddio


    sorry didnt quite read the question - yes round will round up anyway if the value is over 0.49999999999999999999999999999999999 in some languages and what if you start off with 50.002


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    It's real money.


  • Closed Accounts Posts: 695 ✭✭✭yawha


    x = x*100 - (int)(x*100) ? (int)x + 0.01 : (int)x


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    I think the solution is as simple as:

    decimalFormat(x + 0.004)

    e.g.

    49.999 should round to 50.00

    49.999 + 0.004 = 50.003

    decimalFormat(50.003) = 50.00

    50 should remain 50.

    50 + 0.004 = 50.004

    decimalFormat(50.004) = 50.00

    50.001 should round to 50.01

    50.001 + 0.004 = 50.005

    decimalFormat(50.005) = 50.01


  • Closed Accounts Posts: 695 ✭✭✭yawha


    What about 50.0001?


  • Closed Accounts Posts: 17,208 ✭✭✭✭aidan_walsh


    Can you please answer a question when its put to you by a moderator? Again, is this homework?


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    yawha wrote: »
    What about 50.0001?

    :mad:

    Any solution?

    Without going down + 0.44444444444444444444444444444444............


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    MiCr0 wrote: »
    Is this homework?
    It's real money.
    Can you please answer a question when its put to you by a moderator? Again, is this homework?

    No, it is not homework!


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    Latest solution (I am using strings functions also):

    y = (x * 100)

    if (contains(".", y)
    then
    y = y + 1
    y = substringBefore(".", y)

    y = (y / 100)

    Thanks yawha for your help!


  • Closed Accounts Posts: 48 johnsmith13


    It's real money.

    I work in an EPOS company developing the software and can i just say that €50.001 is €50.00 in Real Money

    Is there a reason you are doing this?


  • Registered Users, Registered Users 2 Posts: 1,311 ✭✭✭Procasinator


    Could you not do:
    n = y
    y = decimalFormat(y, "0.00")
    if (n > y) then
        y += 0.01
    

    Making assumption that decimalFormat just truncates other decimal places and doesn't round.


  • Closed Accounts Posts: 18,163 ✭✭✭✭Liam Byrne


    What's wrong with the ceil function for this ?


    $50.001 should go to $50.01
    $50.000 should go to $50.00
    $49.999 should go to $50.00
    $49.989 should go to $49.99

    number_format(ceil($x*100)/100)

    Obviously the exact notation will depend on whether it's Java or JavaScript or PHP


  • Registered Users, Registered Users 2 Posts: 2,781 ✭✭✭amen


    $50.001 should go to $50.01

    That is not correct.

    You are going to run into huge balancing problems if you are doing this.


  • Registered Users, Registered Users 2 Posts: 1,922 ✭✭✭fergalr


    amen wrote: »
    $50.001 should go to $50.01

    That is not correct.

    You are going to run into huge balancing problems if you are doing this.


    What do you mean 'that is not correct'?
    You are quoting an example from the OPs post, where the OP explicitly says they want to round up to the nearest cent.

    It looks like rounding up to the nearest cent, to me.


    Perhaps you mean that the specification is 'not correct' in some sense.
    Have you got additional details on the use case, that aren't mentioned in the thread?
    If not, surely this post:
    I work in an EPOS company developing the software and can i just say that €50.001 is €50.00 in Real Money

    Is there a reason you are doing this?
    has covered it?


    Its just a bit strong to call the specified problem 'not correct', if you have no other information.


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    I work in an EPOS company developing the software and can i just say that €50.001 is €50.00 in Real Money

    Is there a reason you are doing this?

    I'm doing this because this is what the customer wants.
    Could you not do:
    n = y
    y = decimalFormat(y, "0.00")
    if (n > y) then
        y += 0.01
    

    Making assumption that decimalFormat just truncates other decimal places and doesn't round.

    decimalFormat does round, but I think your solution may work anyway?

    n = 49.999
    y = decimalFormat(n, "0.00") = 50.00

    n = 50
    y = decimalFormat(n, "0.00") = 50.00

    n = 50.001
    y = decimalFormat(n, "0.00") = 50.00

    n > y ∴ y = y + 0.01 = 50.01


    Liam Byrne wrote: »
    What's wrong with the ceil function for this ?


    $50.001 should go to $50.01
    $50.000 should go to $50.00
    $49.999 should go to $50.00
    $49.989 should go to $49.99

    number_format(ceil($x*100)/100)

    Obviously the exact notation will depend on whether it's Java or JavaScript or PHP

    The software does not have access to the ceil function. I can add more functions, but it's not practical to do at this stage.
    amen wrote: »
    That is not correct.

    You are going to run into huge balancing problems if you are doing this.

    The customer is always correct! I won't because I'm not involved in balancing the books!
    fergalr wrote: »
    What do you mean 'that is not correct'?
    You are quoting an example from the OPs post, where the OP explicitly says they want to round up to the nearest cent.

    It looks like rounding up to the nearest cent, to me.


    Perhaps you mean that the specification is 'not correct' in some sense.
    Have you got additional details on the use case, that aren't mentioned in the thread?
    If not, surely this post:

    has covered it?


    Its just a bit strong to call the specified problem 'not correct', if you have no other information.

    Thanks for all the help!


  • Closed Accounts Posts: 695 ✭✭✭yawha


    I did answer this in the 4th post: http://www.boards.ie/vbulletin/showpost.php?p=74387209&postcount=4 .

    It's pretty much what Procrastinator did, just using integer casts for truncation rather than your decimalFormat function, which none of us have any idea of how it actually works.

    We also have no idea what language you're using btw, which is a pretty massive issue.


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    Thanks yawha. I said in my last post that the decimalFormat function rounds as normal, below 5 rounds down, 5 and above rounds up.

    It's custom software for XML, with the limited Math functions I mentioned available. I was more looking for an algorithm, using those functions, rather than a language specific solution.


  • Registered Users, Registered Users 2 Posts: 11,989 ✭✭✭✭Giblet


    Without library functions, I suppose it depends on int truncating correctly though ;)
    decimal num = 50.00001;
    decimal result = num;
    if((num * 100) > (int)(num * 100))
    {
      num += .01;	
      result = ((int)(num * 100)) / 100.0;
    }
    


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    Giblet wrote: »
    Without library functions, I suppose it depends on int truncating correctly though ;)
    decimal num = 50.00001;
    decimal result = num;
    if((num * 100) > (int)(num * 100))
    {
      num += .01;	
      result = ((int)(num * 100)) / 100.0;
    }
    

    I can't cast to an int, it's not Java. It's custom software made from Java with it's own editor. I cannot add more helper functions right now.

    This one posted earlier should work and it seems the most efficient and simplest:
    y = decimalFormat(y, "0.00")
    if (n > y) then
        y += 0.01
    

    I have already checked in though:
    y = (x * 100)
    
    if (contains(".", y)
    then
        y = y + 1
        y = substringBefore(".", y)
    y = (y / 100)
    

    It works, but not as elegant or efficient as the previous solution.


  • Registered Users, Registered Users 2 Posts: 1,311 ✭✭✭Procasinator


    yawha wrote: »
    I did answer this in the 4th post: http://www.boards.ie/vbulletin/showpost.php?p=74387209&postcount=4 .

    It's pretty much what Procrastinator did, just using integer casts for truncation rather than your decimalFormat function, which none of us have any idea of how it actually works.

    We also have no idea what language you're using btw, which is a pretty massive issue.

    Pretty much the same logic, though wouldn't your int cast in the true case (i.e. (int)x + 0.01) lead to the incorrect result in most cases?

    Also, is multiplication of 100 necessary?


  • Registered Users, Registered Users 2 Posts: 11,989 ✭✭✭✭Giblet


    Pretty much the same logic, though wouldn't your int cast in the true case (i.e. (int)x + 0.01) lead to the incorrect result in most cases?

    Also, is multiplication of 100 necessary?

    The logic would be to pull the number up two decimal places, truncate, compare with the float (also pulled up two decimals & 1.0 = 1) and if the float is larger, we need to round up 1/100


  • Registered Users, Registered Users 2 Posts: 1,311 ✭✭✭Procasinator


    Giblet wrote: »
    The logic would be to pull the number up two decimal places, truncate, compare with the float (also pulled up two decimals & 1.0 = 1) and if the float is larger, we need to round up 1/100

    I don't fully get you. Are you talking about your code or yahwa's?

    Say we have x is 50.007.

    In yawha's code:

    x*100 - (int)(x*100) = 5000.7 - 5000 = 0.7, which as non-zero evaluates true in his code.

    Without * 100
    x - (int)x = 50.007 - 50 = .007, which also should evaluate to true.

    In his true or false case, he doesn't do ((int)(num * 100)) / 100; to get a number to 2 decimal places, so it isn't used in that way. I can see why you did it that way.


  • Closed Accounts Posts: 2,696 ✭✭✭mark renton


    This looks awfully like homework to me - can we get a mod in here??


  • Closed Accounts Posts: 577 ✭✭✭Galtee


    I don't fully get you. Are you talking about your code or yahwa's?

    Say we have x is 50.007.

    In yawha's code:

    x*100 - (int)(x*100) = 5000.7 - 5000 = 0.7, which as non-zero evaluates true in his code.

    Without * 100
    x - (int)x = 50.007 - 50 = .007, which also should evaluate to true.

    In his true or false case, he doesn't do ((int)(num * 100)) / 100; to get a number to 2 decimal places, so it isn't used in that way. I can see why you did it that way.

    It looks to me as if 100 is there to ensure rounding 3+ decimal places only, so if the input is 50.1 or 50.01 then this will multiply to 5010 and 5001 respectively and hence casting value will match multiplied value and hence won't be rounded. The else output shouldn't be (int)x though as this will return 50.1 as 50 etc. should be just x as far as I can see unless I've missed something.


  • Registered Users, Registered Users 2 Posts: 1,180 ✭✭✭EyeSight


    I work in an EPOS company developing the software and can i just say that €50.001 is €50.00 in Real Money

    Is there a reason you are doing this?
    out of sheer curiosity, would €50.009 = €50 also?
    in money related software is it the standard to always round down no matter how high the offset is??


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    MiCr0 wrote: »
    Is this homework?
    Can you please answer a question when its put to you by a moderator? Again, is this homework?
    john47832 wrote: »
    This looks awfully like homework to me - can we get a mod in here??

    Íosa Críost! :eek:

    books_paranoia_library_266055.jpg

    I already said that it is not homework. Now tell me, even if it was homework, which of these rules and guidelines would I have broken, or failed to follow?

    Again, thanks to all those who took the time to post helpful feedback, it's greatly appreciated!


  • Closed Accounts Posts: 695 ✭✭✭yawha


    Galtee wrote: »
    The else output shouldn't be (int)x though as this will return 50.1 as 50 etc. should be just x as far as I can see unless I've missed something.
    Right you are, it should just be x. Good spot.

    I can't edit it for some reason, so:

    x = x*100 - (int)(x*100) ? (int)x + 0.01 : x

    With an if statement (this is actually probably shorter):
    if (x * 100 != (int)(x * 100) )
       x = (int)x + 0.01
    


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 11,989 ✭✭✭✭Giblet


    yawha wrote: »
    Right you are, it should just be x. Good spot.

    I can't edit it for some reason, so:

    x = x*100 - (int)(x*100) ? (int)x + 0.01 : x

    With an if statement (this is actually probably shorter):
    if (x * 100 != (int)(x * 100) )
       x = (int)x + 0.01
    


    That won't work, you truncate x and add .01, so you'll always have x.01 as the number if there is a remainder in the 100's or less.
    x +- .01f;
    x = ((int)x * 100) / 100.0f
    
    This will truncate after two decimal places correctly


  • Moderators, Technology & Internet Moderators Posts: 1,336 Mod ✭✭✭✭croo


    EyeSight wrote: »
    out of sheer curiosity, would €50.009 = €50 also?
    in money related software is it the standard to always round down no matter how high the offset is??
    Not to fork the OP's thread... but there are many rounding methods. The most common being round half up ... which most people are familiar with and would round your €50.009 to €50.01. But one method I came across is called "bankers' rounding" or "round half to even" where, as its name implies, it only rounds up (after half) to an even number. When I happened across the bankers' rounding I thought it must be an error but wikipedia has a good article on the subject that enlightened me http://en.wikipedia.org/wiki/Rounding


  • Registered Users, Registered Users 2 Posts: 3,305 ✭✭✭irishguy


    I used to work for a large bank they used either 6 or 8 digits after the decimal place. If you apply it consistently to all transactions (ensure your OS and Database support this) then you will have Zero balancing problems.


  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    I found a list of rounding algorithms here: Rounding Algorithms 101

    # Round-Ceiling (Positive Infinity)
    # Round-Away From-Zero

    These are what my case needed.

    round-summary.gif


  • Closed Accounts Posts: 2,696 ✭✭✭mark renton


    ^^

    looks to me it may have come from your text book :D


  • Closed Accounts Posts: 695 ✭✭✭yawha


    Giblet wrote: »
    That won't work, you truncate x and add .01, so you'll always have x.01 as the number if there is a remainder in the 100's or less.
    x +- .01f;
    x = ((int)x * 100) / 100.0f
    
    This will truncate after two decimal places correctly
    God dammit. Brain was not functioning. You're correct.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 3,078 ✭✭✭onemorechance


    john47832 wrote: »
    ^^

    looks to me it may have come from your text book :D

    129176578250159225.jpg


Advertisement