Author | Topic: Re: Bug in Function CEILING (XBTools)?? | |
---|---|---|
Paul Chong | Re: Bug in Function CEILING (XBTools)?? on Sat, 25 Aug 2018 11:59:07 +0800 Hi All, I have reconfirmed that this problem is still unsolved. Does anyone has a solution or work around? TIA Paul On Wed, 21 Jun 2006 16:02:26 +0200, Rene Langer wrote: > Hello all, > > To make a round up for a number I wrote following function: > > FUNCTION RoundUP(nValue, nDecimals) > RETURN( CEILING(nValue * (10 ^ nDecimals)) / (10 ^ nDecimals) ) > > Some Tests: > > RoundUP(4.912, 2) -> 4.92 OK > RoundUP(4.901, 2) -> 4.91 OK > RoundUP(4.9, 2) -> 4.91 ?????? > RoundUP(4.93, 2) -> 4.93 OK > RoundUP(4.94, 2) -> 4.95 ?????? > > Any idea?????? > > using xb 1.82.294, winxp > > Thanks for help, > > Rene > > PS: Same Problem with function "round_down" using xbtools func FLOOR(..) | |
Jonathan Leeming | Re: Bug in Function CEILING (XBTools)?? on Sat, 25 Aug 2018 16:38:24 -0600 On 8/24/2018 9:59 PM, Paul Chong wrote: > Hi All, > > I have reconfirmed that this problem is still unsolved. Does anyone has a > solution or work around? > > TIA > > Paul > > On Wed, 21 Jun 2006 16:02:26 +0200, Rene Langer wrote: > >> Hello all, >> >> To make a round up for a number I wrote following function: >> >> FUNCTION RoundUP(nValue, nDecimals) >> RETURN( CEILING(nValue * (10 ^ nDecimals)) / (10 ^ nDecimals) ) >> >> Some Tests: >> >> RoundUP(4.912, 2) -> 4.92 OK >> RoundUP(4.901, 2) -> 4.91 OK >> RoundUP(4.9, 2) -> 4.91 ?????? >> RoundUP(4.93, 2) -> 4.93 OK >> RoundUP(4.94, 2) -> 4.95 ?????? >> >> Any idea?????? >> >> using xb 1.82.294, winxp >> >> Thanks for help, >> >> Rene >> >> PS: Same Problem with function "round_down" using xbtools func FLOOR(..) Hi Paul, Although I expect Andreas Gehrs-Pahl will chime in with the best solution I found that the roundup problem could be resolved by enclosing the nValue * (10 ^ nDecimals) within VAL(STR()) so the function would be... FUNCTION RoundUP(nValue, nDecimals) RETURN CEILING(VAL(STR(nValue * (10 ^ nDecimals)))) / (10 ^ nDecimals) This appears to give the correct return values for the samples presented. I originally thought I would have to perform VAL(STR()) on the entire return value but that does not appear to be necessary. The VAL(STR()) seems to correct what I believe is an internal calculations precision rounding issue. In a previous posting of Andreas he said: "This issue is caused by the way decimal floating point numbers are represented and manipulated in binary format, using the IEEE 754 standard. And as Xbase++ doesn't have BCD (Binary-Coded Decimal) math routines, the limitation of the IEEE 754 standard will be what you have to live with." I'm guessing this is what is going on here. Hope this helps... Jonathan Andreas where are you jonathan.leeming@the-family-centre.com Edmonton, Alberta, Canada | |
Paul Chong | Re: Bug in Function CEILING (XBTools)?? on Mon, 27 Aug 2018 17:53:55 +0800 Hi Jonathan Thank you for your reply. Maybe Andreas Gehrs-Pahl is busy, but your solution is good enough, at least on 2 decimal places. I have added more samples with different decimal place & -ve value. However some samples break the code. RoundUP(3.2,0) 4 ok RoundUP(76.9,0) 77 ok RoundUP(3.14159, 3) 3.14 X 3.142 RoundUP(-3.14159, 1) -3.1 X -3.2 RoundUP(31415.92654, -2) 31500 ok I use a data capture to see how the data & formula evolve. This is my finding. The VAL(STR()) really correct the rounding issue caused by the '*', '/' & maybe the Ceiling() too. So to fix the issue on different decimal places, i added another VALSTR()) & specifies the no of decimal places to the entire return value. To fix -ve nValue, i added a control sign. Hence the new function. FUNCTION RoundUP(nValue, nDecimals) LOCAL nSign := IIF(nValue<0,-1,1) nValue *= nSign RETURN VAL(STR(CEILING(VAL(STR(nValue * (10 ^ nDecimals)))) / (10 ^ nDecimals) * nSign,,nDecimals)) The result practically match all the samples i have collected. Thanks again for the solution & hopefully others may benefit from it. Paul RoundUp(3.2,0): 4 RoundUp(76.9,0): 77 RoundUp(3.14459, 3): 3.145 RoundUp(3.14159, 3): 3.142 RoundUp(-3.14159, 1): -3.2 RoundUp(31415.92654, -2): 31500 RoundUp(4.912, 2): 4.92 RoundUp(4.901, 2): 4.91 RoundUp(4.9, 2): 4.90 RoundUp(4.93, 2): 4.93 RoundUp(4.94, 2): 4.94 RoundUp(5.1241, 0): 6 RoundUp(5.1241, 1): 5.2 RoundUp(5.1241, 2): 5.13 RoundUp(5.1241, 3): 5.125 RoundUp(27842.5, -1): 27850 RoundUp(27842.5, -2): 27900 RoundUp(27842.5, -3): 28000 RoundUp(5.82, 0): 6 RoundUp(-5.82, 0): -6 RoundUp(5.82, 1): 5.9 RoundUp(-5.82, 1): -5.9 RoundUp(123.456, -1): 130 RoundUp(-123.456, -1): -130 RoundUp(123.456, -2): 200 RoundUp(-123.456, -2): -200 RoundUp(0.0000123, -3): 1000 RoundUp(-0.0000123, -3): -1000 On Sat, 25 Aug 2018 16:38:24 -0600, Jonathan Leeming wrote: > On 8/24/2018 9:59 PM, Paul Chong wrote: >> Hi All, >> >> I have reconfirmed that this problem is still unsolved. Does anyone has a >> solution or work around? >> >> TIA >> >> Paul >> >> On Wed, 21 Jun 2006 16:02:26 +0200, Rene Langer wrote: >> >>> Hello all, >>> >>> To make a round up for a number I wrote following function: >>> >>> FUNCTION RoundUP(nValue, nDecimals) >>> RETURN( CEILING(nValue * (10 ^ nDecimals)) / (10 ^ nDecimals) ) >>> >>> Some Tests: >>> >>> RoundUP(4.912, 2) -> 4.92 OK >>> RoundUP(4.901, 2) -> 4.91 OK >>> RoundUP(4.9, 2) -> 4.91 ?????? >>> RoundUP(4.93, 2) -> 4.93 OK >>> RoundUP(4.94, 2) -> 4.95 ?????? >>> >>> Any idea?????? >>> >>> using xb 1.82.294, winxp >>> >>> Thanks for help, >>> >>> Rene >>> >>> PS: Same Problem with function "round_down" using xbtools func FLOOR(..) > > Hi Paul, > > Although I expect Andreas Gehrs-Pahl will chime in with the best > solution I found that the roundup problem could be resolved by enclosing > the nValue * (10 ^ nDecimals) within VAL(STR()) so the function would be... > > FUNCTION RoundUP(nValue, nDecimals) > RETURN CEILING(VAL(STR(nValue * (10 ^ nDecimals)))) / (10 ^ nDecimals) > > This appears to give the correct return values for the samples > presented. I originally thought I would have to perform VAL(STR()) on > the entire return value but that does not appear to be necessary. > > The VAL(STR()) seems to correct what I believe is an internal > calculations precision rounding issue. > > In a previous posting of Andreas he said: > > "This issue is caused by the way decimal floating point numbers are > represented and manipulated in binary format, using the IEEE 754 > standard. And as Xbase++ doesn't have BCD (Binary-Coded Decimal) math > routines, the limitation of the IEEE 754 standard will be what you have > to live with." > > I'm guessing this is what is going on here. > > Hope this helps... Jonathan > > Andreas where are you |