Serious round() problem

Ask a Question related to Macromedia ColdFusion, Design and Development.

  1. #1

    Default Serious round() problem

    I just discovered an error (with serious consequences) in my code. When I write

    #Round((0.5053*100) * 250)#

    I get 12632. But when I write

    #Round(50.53 * 250)#

    I get 12633. Which is of course rather surprising at first sight because
    mathematically both should have the same result. I suppose this has to do with
    the way decimal numbers are converted to floating point binary numbers. But it
    scares me because in my program these numbers are amounts of money and they
    should be correct. There are official rules in my company about how to
    calculate and round numbers (with euro and eurocents). The second result
    (12633) is correct to me, but the problem is that the numbers 0.5053 and 250
    (could be anything else) are coming directly from the database and that I must
    multiply them first with 100 in my code (so I always get the wrong result).
    It's worse: this kind of rounding happens many times on almost all of my pages.
    How can I correct this situation or deal with it? Of course this error isn't
    seen with every random number.

    ldetant2 Guest

  2. Similar Questions and Discussions

    1. Round Corners in CSS
      Hi, I was wondering if anyone knew how to create round corners in CSS w/o adding an image to the top/bottom - left/right corners. Is there a...
    2. #24876 [NEW]: Round does not round properly
      From: jeff at tmtrading dot com Operating system: Redhat 8.0 PHP version: 4CVS-2003-07-30 (stable) PHP Bug Type: Math related...
    3. #24828 [Asn->Csd]: round() function doesn't round !
      ID: 24828 Updated by: edink@php.net Reported By: christophe dot bidaux at netcourrier dot com -Status: Assigned...
    4. #24828 [Opn->Asn]: round() function doesn't round !
      ID: 24828 Updated by: iliaa@php.net Reported By: christophe dot bidaux at netcourrier dot com -Status: Open...
    5. #24828 [NEW]: round() function doesn't round !
      From: christophe dot bidaux at netcourrier dot com Operating system: Windows 98SE PHP version: 4CVS-2003-07-27 (stable) PHP Bug...
  3. #2

    Default Re: Serious round() problem

    hi

    yeap...i think there is a problem with CF when rounding the value.
    try this way if possible:

    #round(100*250*.5053)#
    vkunirs Guest

  4. #3

    Default Re: Serious round() problem

    Thanks for the quick reply. This does return the correct result in this case,
    with these numbers. But there can stil be cases where this doesn't work. Take
    for example:

    #Round(100 * 12.4737 * 50)#

    This has the result 62368. But it should be 62369. So it's still not correct.

    ldetant2 Guest

  5. #4

    Default Re: Serious round() problem

    hi

    I think by seeing all these things it better to do it manually like this.

    <cFSET X="12345.3">
    <cfif #val(mid(X,find(".",X)+1,len(x)))# gte 5 >
    #round(x)#
    <Cfelse>
    #Int(x)#
    </cfif>

    try this with your requirements...if you still has the problem let post it
    here...

    vkunirs Guest

  6. #5

    Default Re: Serious round() problem

    Thanks, this indeed looks as a simple but correct alternative. Haven't tried it
    out though because I tried a similar approach: instead of writing:

    #Round( X * Y * Z)#

    I now write:

    #Round(Val(ToString(X * Y * Z)))#

    Up until now this always gives the correct result. But thanks for your advice.
    I'll post your answer in my archive also, so if my approach will show leaks in
    a few days, I'll try yours. Thanks to you and to the forum. This was a great
    help and i'm more assured now. Because I never write the Round() function
    anywhere in my code pages. I created a ColdFusion function which does the
    rounding for me. So simply adapting that function (which I placed in
    Application.cfm) has solved all the rounding problems on all my pages (which
    is a lot!) at once.

    Lieven



    ldetant2 Guest

  7. #6

    Default Re: Serious round() problem

    Hmm... You accepted and is going to advertise absolutely incorrect solution...

    The physics of this problem, as you partially mentioned yourself, is in
    differences between an ideal math and the math with approximate numbers. In
    your case, you are getting different results, because (0.5053*100) and 53.50
    are DIFFERENT numbers (from computer's point of view, of course). Therefore,
    you are rounding different numbers and getting [correct] different results.

    Converting numbers to strings has very little to do with the real solution,
    even it (amazingly) helps sometimes. And it helps, because when you do the
    conversion, CF implicitly applies an internal default rounding algorithm
    (different in different versions - and now Java version dependent). If you
    want to be in control (you are counting money, as far as I understand), you
    should not do this.

    The correct approach would be applying your own rounding rules explicitly.
    So, if 0.5053 is the number of euros and you want to get the number of cents
    with the 2-decimal precision, you should:

    <cfset cents=NumberFormat(0.5053 * 100, "____________.__")>
    <cfset res=Round(cents*250)>

    Also, it is a good idea to setup fields in your database as DECIMAL, not as
    FLOAT or REAL.. Also, before inserting a value in the database, make sure you
    have the right precision, otherwise CF again will "fireindy" round it for you.
    And not necceseraly the way you expect.

    Another common approach is to use integer math everywhere, where possible. If
    your calculations go only up to whole cents, keep all numbers as integer cents,
    not as floating point euros. If you need decimal places, use an appropriate
    scale.

    In your previous example:

    <!--- Convert to integer --->
    <cfset cents=Round(0.5053*1000)>
    . . . . . . do some stuff on inetegers only. . . . . .
    . . . . . . convert result back . . . . . .
    <cfset result=NumberFormat(0.0001*result, . . . . . .>


    P.S. Dollars behave similary





    Mr Black Guest

  8. #7

    Default Re: Serious round() problem

    That is just a bug.

    12632.5 shouldn't round to 12632 and you shouldn't have to go through all those girations to get it to round properly.

    Hopefully MM will fix it.
    Brian Philippus Guest

  9. #8

    Default Re: Serious round() problem

    Before reporting bug, just try this first:

    <cfoutput>
    #NumberFormat(0.5053*100, "___._______________________________")#
    #Round((0.5053*100) * 250)#<br>
    #NumberFormat(50.53, "___._______________________________")# #Round(50.53 *
    250)#<br>
    </cfoutput>


    Mr Black Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139