home bbs files messages ]

Just a sample of the Echomail archive

<< oldest | < older | list | newer > | newest >> ]

 Message 135 
 Wolfgang Ehrhardt to All 
 Re: exp bug in Virtual Pascal and bpl70v 
 16 Jan 11 22:28:00 
 
p.lang.pascal.borland:412
From: WE@completely.invalid (Wolfgang Ehrhardt)

On Sun, 16 Jan 2011 20:13:26 +0000, Robert AH Prins
 wrote:
>Two more replies from Norbert Juffa:
...
>I got repro. The failing input is 4003_A65AF678_54B28211. With rounding 
>to positive infinity, multiplying the input by L2E gives 30.0 + 1 ulp. 
>FRNDINT then rounds this up further to 31.0. Things are already 
>irreparably screwed up at this point. In any event, the input to F2XM1 
>becomes -(1.0 + 1 ulp), which is clearly out of bounds. On my CPU it 
>returns the unmodified input operand in this case.

Meanwhile I found that the unmodified code has a lot more errors for
rmTruncate with negative x arguments: here are the smallest values
found (also with hex dumps for better reference), the positive
arguments give wrong results with rmUp the negative with rmTruncate.

        x               exp(x)                 x as LSB Hex
-6.238324625040 -1.27054942088145051E-0021  C001C7A05AF6CC0968E2
-7.624618986159 -3.17637355220362627E-0022  C001F3FCE0F4C07D474D
-8.317766166719 -5.29395592033937712E-0023  C002851591F9DD5B9B41
-9.010913347279 -7.94093388050906568E-0023  C002902CB3795A7892DC

 6.238324625040 -1.11022302462515654E-0016  4001C7A05AF6CC0968E1
 7.624618986159 -4.44089209850062616E-0016  4001F3FCE0F4C07D474C
12.476649250079 -1.13686837721616030E-0013  4002C7A05AF6CC0968E1
15.249237972319 -1.81898940354585648E-0012  4002F3FCE0F4C07D474C

>The only reasonable workaround for this that I can see is to reduce the 
>input to F2XM1 further, to make sure we are definitely inside the 
>interval supported by the hardware. In other words, replace F2MX1 by the 
>following instruction sequence:
>
>  fmul  dword ptr [half]   ; 0.5*frac(z) int(z)
>  f2mx1                    ; 2^(0.5*frac(z))-1 int(z)
>  fld   st(0)              ; 2^(0.5*frac(z))-1 2^(0.5*frac(z))-1 int(z)
>  fadd  dword ptr [two]    ; 2^(0.5*frac(z))+1 2^(0.5*frac(z))-1 int(z)
>  fmulp st(1),st           ; 2^frac(z)-1 int(z)
>
This code does not show the errors and seems to work ok (Note that
there is a small type f2mx1 must be changed to f2xm1; and the
constants should be single). The priced to pay is a small decrease in
accuracy, here the result for 20000 random arguments with standard
round to nearest (the error is calculated with my MPArith routines):

 ------ Old version ------
Test of amath.exp
at 10000 random values in [-100.0000000000 .. 100.0000000000]
RMS = 0.24, max rel = 0.71 eps at 
 x(ext) =  7.24700653776128467E+0001 = $400590F0AC68BFA87B80
 y(ext) =  2.97405843003663398E+0031 = $4067BBB0815EA0230490
 y(mpf) = +2.97405843003663397839071382253654488039888365036E+31

Test of amath.exp
at 10000 random values in [100.0000000000 .. 10000.0000000000]
RMS = 0.24, max rel = 0.72 eps at 
 x(ext) =  4.80456952900561126E+0003 = $400B96248E653929CA47
 y(ext) =  3.96309394729273526E+2086 = $5B12B8A5DD42BAF8E736
 y(mpf) = +3.96309394729273526538566268155478642708748950161E+2086

 ------ New version ------
Test of amath.exp
at 10000 random values in [-100.0000000000 .. 100.0000000000]
RMS = 0.25, max rel = 0.83 eps at
 x(ext) =  1.83770128884148676E+0001 = $400393041F554F4C8000
 y(ext) =  9.57271857222288938E+0007 = $4019B695CA371C7FC4DE
 y(mpf) = +9.57271857222288937714622943945524368866640537394E+7

Test of amath.exp
at 10000 random values in [100.0000000000 .. 10000.0000000000]
RMS = 0.24, max rel = 0.83 eps at
 x(ext) =  5.98844546289204336E+0003 = $400BBB23904ED947432E
 y(ext) =  5.60815118133691577E+2600 = $61BEB51753447EF41B4A
 y(mpf) = +5.60815118133691576592733747663153598713873826468E+2600

>If there is consensus that Pascal math functions shall work properly 
>when the dynamic rounding mode is not round-to-nearest-even, I believe 
>this is the way to go (least impact on execution time).
>
>I dug out my old Pascal manuals and can't find anything about the 
>prescribed behavior of math functions when a user dials in some rounding 
>mode different from the default. Given the naive approach to exp() 
>computation in Borland's original library, it is quite possible that it 
>happened to work as desired in round-up mode. My question is: is that to 
>be considered an implementation artifact or a feature?

I guess it is a pure accident, especially as Borland Pascal has no
library functions for getting/setting rounding modes. The situation is
a bit different for Virtual Pascal and Delphi. But IMO at least the
Delphi math unit designer/implementers did not understand there task.
My AMath unit is an attempt to overcome these Delphi shortcomings. 

Robert: Please forward a big "Thank you" to Norbert.

Wolfgang
-- 
Do not use the e-mail address from the header! You can get a
valid address from http://home.netsurf.de/wolfgang.ehrhardt
(Free open source Crypto, CRC/Hash, MPArith for Pascal/Delphi)

--- Internet Rex 2.31
 * Origin: The gateway at Omicron Theta (1:261/20.999)

<< oldest | < older | list | newer > | newest >> ]

(c) 1994,  bbs@darkrealms.ca