Alaska Software Inc. - Re: Bug in Function CEILING (XBTools)??
Username: Password:
AuthorTopic: Re: Bug in Function CEILING (XBTools)??
Paul ChongRe: 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 LeemingRe: 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 ChongRe: 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