On 10/20/18 9:47 AM, Giuliano Augusto Faulin Belinassi wrote: > So I did some further investigation comparing the ULP error. > > With the formula that Wilco Dijkstra provided, there are cases where > the substitution is super precise. > With floats: > with input : = 9.99999940395355224609375000000000000000000000000000e-01 > sinh: before: = 2.89631005859375000000000000000000000000000000000000e+03 > sinh: after : = 2.89630932617187500000000000000000000000000000000000e+03 > sinh: mpfr : = 2.89630924626497842670468162463283783344599446025119e+03 > ulp err befr: = 3 > ulp err aftr: = 0 > > With doubles: > with input : = 9.99999999999999888977697537484345957636833190917969e-01 > sinh: before: = 6.71088640000000298023223876953125000000000000000000e+07 > sinh: after : = 6.71088639999999925494194030761718750000000000000000e+07 > sinh: mpfr : = 6.71088639999999944120645523071287770030292885894208e+07 > ulp err befr: = 3 > ulp err aftr: = 0 > > *However*, there are cases where some error shows up. The biggest ULP > error that I could find was 2. > > With floats: > with input : = 9.99968349933624267578125000000000000000000000000000e-01 > sinh: before: = 1.25686134338378906250000000000000000000000000000000e+02 > sinh: after : = 1.25686149597167968750000000000000000000000000000000e+02 > sinh: mpfr : = 1.25686137592274042266452526368087062890399889097864e+02 > ulp err befr: = 0 > ulp err aftr: = 2 > > With doubles: > with input : = 9.99999999999463651256803586875321343541145324707031e-01 > sinh: before: = 9.65520209507428342476487159729003906250000000000000e+05 > sinh: after : = 9.65520209507428109645843505859375000000000000000000e+05 > sinh: mpfr : = 9.65520209507428288553227922831618987450806468855883e+05 > ulp err befr: = 0 > ulp err aftr: = 2 > > And with FMA we have the same results showed above. (super precise > cases, and maximum ULP error equal 2). > > So maybe update the patch with the following rules? > * If FMA is available, then compute 1 - x*x with it. > * If FMA is not available, then do the dijkstra substitution when |x| > > 0.5. So I think the runtime math libraries shoot for .5 ULP (yes, they don't always make it, but that's their goal). We should probably have the same goal. Going from 0 to 2 ULPs would be considered bad.
So ideally we'd have some way to distinguish between the cases where we actually improve things (such as in your example). I don't know if that's possible. jeff