1 /* $OpenBSD: monotl.c,v 1.2 2011/07/08 16:49:05 martynas Exp $ */
2
3 /*
4 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /* monotl.c
20 Floating point function test vectors.
21
22 Arguments and function values are synthesized for NPTS points in
23 the vicinity of each given tabulated test point. The points are
24 chosen to be near and on either side of the likely function algorithm
25 domain boundaries. Since the function programs change their methods
26 at these points, major coding errors or monotonicity failures might be
27 detected.
28
29 August, 1998
30 S. L. Moshier */
31
32 #include <float.h>
33
34 #if LDBL_MANT_DIG == 64
35 /* Unit of error tolerance in test[i].thresh. */
36 static long double MACHEPL =
37 5.42101086242752217003726400434970855712890625E-20L;
38 /* How many times the above error to allow before printing a complaint.
39 If TOL < 0, consider absolute error instead of relative error. */
40 #define TOL 8
41 /* Number of test points to generate on each side of tabulated point. */
42 #define NPTS 100
43
44
45
46 #include <stdio.h>
47
48
49 /* Avoid including math.h. */
50 long double frexpl (long double, int *);
51 long double ldexpl (long double, int);
52
53 /* Functions of one variable. */
54 long double expl (long double);
55 long double logl (long double);
56 long double sinl (long double);
57 long double cosl (long double);
58 long double tanl (long double);
59 long double atanl (long double);
60 long double asinl (long double);
61 long double acosl (long double);
62 long double sinhl (long double);
63 long double coshl (long double);
64 long double tanhl (long double);
65 long double asinhl (long double);
66 long double acoshl (long double);
67 long double atanhl (long double);
68 long double lgammal (long double);
69 long double tgammal (long double);
70 long double fabsl (long double);
71 long double floorl (long double);
72 long double j0l (long double);
73 long double y0l (long double);
74 long double j1l (long double);
75 long double y1l (long double);
76
77 /* Data structure of the test. */
78 struct oneargument
79 {
80 char *name; /* Name of the function. */
81 long double (*func) (long double); /* Function call. */
82 long double arg1; /* Function argument, assumed exact. */
83 long double answer1; /* Exact number, close to function value. */
84 long double answer2; /* answer1 + answer2 has extended precision. */
85 long double derivative; /* dy/dx evaluated at x = arg1. */
86 /* Error report threshold. 2 => 1 ulp approximately
87 if thresh < 0 then consider absolute error instead of relative error. */
88 int thresh;
89
90 };
91
92
93
94 static struct oneargument test1[] =
95 {
96 {"exp", expl, 1.0L, 2.7182769775390625L,
97 4.85091998273536028747e-6L, 2.71828182845904523536L, TOL},
98 {"exp", expl, -1.0L, 3.678741455078125e-1L,
99 5.29566362982159552377e-6L, 3.678794411714423215955e-1L, TOL},
100 {"exp", expl, 0.5L, 1.648712158203125L,
101 9.1124970031468486507878e-6L, 1.64872127070012814684865L, TOL},
102 {"exp", expl, -0.5L, 6.065216064453125e-1L,
103 9.0532673209236037995e-6L, 6.0653065971263342360e-1L, TOL},
104 {"exp", expl, 2.0L, 7.3890533447265625L,
105 2.75420408772723042746e-6L, 7.38905609893065022723L, TOL},
106 {"exp", expl, -2.0L, 1.353302001953125e-1L,
107 5.08304130019189399949e-6L, 1.3533528323661269189e-1L, TOL},
108 {"log", logl, 1.41421356237309492343L, 3.465728759765625e-1L,
109 7.1430341006605745676897e-7L, 7.0710678118654758708668e-1L, TOL},
110 {"log", logl, 7.07106781186547461715e-1L, -3.46588134765625e-1L,
111 1.45444856522566402246e-5L, 1.41421356237309517417L, TOL},
112 {"sin", sinl, 7.85398163397448278999e-1L, 7.0709228515625e-1L,
113 1.4496030297502751942956e-5L, 7.071067811865475460497e-1L, TOL},
114 {"sin", sinl, -7.85398163397448501044e-1L, -7.071075439453125e-1L,
115 7.62758764840238811175e-7L, 7.07106781186547389040e-1L, TOL},
116 {"sin", sinl, 1.570796326794896558L, 9.999847412109375e-1L,
117 1.52587890625e-5L, 6.12323399573676588613e-17L, TOL},
118 {"sin", sinl, -1.57079632679489678004L, -1.0L,
119 1.29302922820150306903e-32L, -1.60812264967663649223e-16L, TOL},
120 {"sin", sinl, 4.712388980384689674L, -1.0L,
121 1.68722975549458979398e-32L, -1.83697019872102976584e-16L, TOL},
122 {"sin", sinl, -4.71238898038468989604L, 9.999847412109375e-1L,
123 1.52587890625e-5L, 3.83475850529283315008e-17L, TOL},
124 {"cos", cosl, 3.92699081698724139500E-1L, 9.23873901367187500000E-1L,
125 5.63114409926198633370E-6L, -3.82683432365089757586E-1L, TOL},
126 {"cos", cosl, 7.85398163397448278999E-1L, 7.07092285156250000000E-1L,
127 1.44960302975460497458E-5L, -7.07106781186547502752E-1L, TOL},
128 {"cos", cosl, 1.17809724509617241850E0L, 3.82675170898437500000E-1L,
129 8.26146665231415693919E-6L, -9.23879532511286738554E-1L, TOL},
130 {"cos", cosl, 1.96349540849362069750E0L, -3.82690429687500000000E-1L,
131 6.99732241029898567203E-6L, -9.23879532511286785419E-1L, TOL},
132 {"cos", cosl, 2.35619449019234483700E0L, -7.07107543945312500000E-1L,
133 7.62758765040545859856E-7L, -7.07106781186547589348E-1L, TOL},
134 {"cos", cosl, 2.74889357189106897650E0L, -9.23889160156250000000E-1L,
135 9.62764496328487887036E-6L, -3.82683432365089870728E-1L, TOL},
136 {"cos", cosl, 3.14159265358979311600E0L, -1.00000000000000000000E0L,
137 7.49879891330928797323E-33L, -1.22464679914735317723E-16L, TOL},
138 {"tan", tanl, 7.85398163397448278999E-1L, 9.999847412109375e-1L,
139 1.52587890624387676600E-5L, 1.99999999999999987754E0L, TOL},
140 {"tan", tanl, 1.17809724509617241850E0L, 2.41419982910156250000E0L,
141 1.37332715322352112604E-5L, 6.82842712474618858345E0L, TOL},
142 {"tan", tanl, 1.96349540849362069750E0L, -2.41421508789062500000E0L,
143 1.52551752942854759743E-6L, 6.82842712474619262118E0L, TOL},
144 {"tan", tanl, 2.35619449019234483700E0L, -1.00001525878906250000E0L,
145 1.52587890623163029801E-5L, 2.00000000000000036739E0L, TOL},
146 {"tan", tanl, 2.74889357189106897650E0L, -4.14215087890625000000E-1L,
147 1.52551752982565655126E-6L, 1.17157287525381000640E0L, TOL},
148 {"atan", atanl, 4.14213562373094923430E-1L, 3.92684936523437500000E-1L,
149 1.41451752865477964149E-5L, 8.53553390593273837869E-1L, TOL},
150 {"atan", atanl, 1.0L, 7.85385131835937500000E-1L,
151 1.30315615108096156608E-5L, 0.5L, TOL},
152 {"atan", atanl, 2.41421356237309492343E0L, 1.17808532714843750000E0L,
153 1.19179477349460632350E-5L, 1.46446609406726250782E-1L, TOL},
154 {"atan", atanl, -2.41421356237309514547E0L, -1.17810058593750000000E0L,
155 3.34084132752141908545E-6L, 1.46446609406726227789E-1L, TOL},
156 {"atan", atanl, -1.0L, -7.85400390625000000000E-1L,
157 2.22722755169038433915E-6L, 0.5L, TOL},
158 {"atan", atanl, -4.14213562373095145475E-1L, -3.92700195312500000000E-1L,
159 1.11361377576267665972E-6L, 8.53553390593273703853E-1L, TOL},
160 {"asin", asinl, 3.82683432365089615246E-1L, 3.92684936523437500000E-1L,
161 1.41451752864854321970E-5L, 1.08239220029239389286E0L, TOL},
162 {"asin", asinl, 0.5L, 5.23590087890625000000E-1L,
163 8.68770767387307710723E-6L, 1.15470053837925152902E0L, TOL},
164 {"asin", asinl, 7.07106781186547461715E-1L, 7.85385131835937500000E-1L,
165 1.30315615107209645016E-5L, 1.41421356237309492343E0L, TOL},
166 {"asin", asinl, 9.23879532511286738483E-1L, 1.17808532714843750000E0L,
167 1.19179477349183147612E-5L, 2.61312592975275276483E0L, TOL},
168 {"asin", asinl, -0.5L, -5.23605346679687500000E-1L,
169 6.57108138862692289277E-6L, 1.15470053837925152902E0L, TOL},
170 {"asin", asinl, 1.16415321826934814453125e-10L,
171 1.16415321826934814453125e-10L, 2.629536350736706018055e-31L,
172 1.0000000000000000000067762L, TOL},
173 {"asin", asinl, 1.0000000000000000000183779E-10L,
174 9.9999999979890480394928431E-11L, 2.0109519607076028264987890E-20L,
175 1.0L, TOL},
176 {"asin", asinl, 1.0000000000000000000007074E-8L,
177 9.9999999999948220585910263E-9L, 5.1781080827147808155022014E-21L,
178 1.0L, TOL},
179 {"asin", asinl, 0.97499847412109375L, 1.346710205078125L,
180 3.969526822009922560999e-6L, 4.500216008585875735254L, TOL},
181 {"acos", acosl, 1.95090322016128192573E-1L, 1.37443542480468750000E0L,
182 1.13611408471185777914E-5L, -1.01959115820831832232E0L, TOL},
183 {"acos", acosl, 3.82683432365089615246E-1L, 1.17808532714843750000E0L,
184 1.19179477351337991247E-5L, -1.08239220029239389286E0L, TOL},
185 {"acos", acosl, 0.5L, 1.04719543457031250000E0L,
186 2.11662628524615421446E-6L, -1.15470053837925152902E0L, TOL},
187 {"acos", acosl, 7.07106781186547461715E-1L, 7.85385131835937500000E-1L,
188 1.30315615108982668201E-5L, -1.41421356237309492343E0L, TOL},
189 {"acos", acosl, 9.23879532511286738483E-1L, 3.92684936523437500000E-1L,
190 1.41451752867009165605E-5L, -2.61312592975275276483E0L, TOL},
191 {"acos", acosl, 9.80785280403230430579E-1L, 1.96334838867187500000E-1L,
192 1.47019821746724723933E-5L, -5.12583089548300990774E0L, TOL},
193 {"acos", acosl, -0.5L, 2.09439086914062500000E0L,
194 4.23325257049230842892E-6L, -1.15470053837925152902E0L, TOL},
195 {"sinh", sinhl, 1.0L, 1.17518615722656250000E0L,
196 1.50364172389568823819E-5L, 1.54308063481524377848E0L, TOL},
197 {"sinh", sinhl, 7.09089565712818057364E2L, 4.49423283712885057274E307L,
198 1.70878916528708958045E289L, 4.49423283712885057274E307L, TOL},
199 {"sinh", sinhl, 2.22044604925031308085E-16L, 0.00000000000000000000E0L,
200 2.22044604925031308085E-16L, 1.00000000000000000000E0L, TOL},
201 {"sinh", sinhl, 3.7252902984619140625e-9L, 3.7252902984619140625e-9L,
202 8.616464714094038285889380656847999229E-27L,
203 1.00000000000000000693889L, TOL},
204 {"sinh", sinhl, 2.3283064365386962890625e-10L, 2.3283064365386962890625e-10L,
205 2.103629080589364814436978072135626630E-30,
206 1.000000000000000000027105L, TOL},
207 {"cosh", coshl, 7.09089565712818057364E2L, 4.49423283712885057274E307L,
208 1.70878916528708958045E289L, 4.49423283712885057274E307L, TOL},
209 {"cosh", coshl, 1.0L, 1.54307556152343750000E0L,
210 5.07329180627847790562E-6L, 1.17520119364380145688E0L, TOL},
211 {"cosh", coshl, 0.5L, 1.12762451171875000000E0L,
212 1.45348763078522622516E-6L, 5.21095305493747361622E-1L, TOL},
213 {"tanh", tanhl, 0.5L, 4.62112426757812500000E-1L,
214 4.73050219725850231848E-6L, 7.86447732965927410150E-1L, TOL},
215 {"tanh", tanhl, 5.49306144334054780032E-1L, 4.99984741210937500000E-1L,
216 1.52587890624507506378E-5L, 7.50000000000000049249E-1L, TOL},
217 {"tanh", tanhl, 0.625L, 5.54595947265625000000E-1L,
218 3.77508375729399903910E-6L, 6.92419147969988069631E-1L, TOL},
219 {"asinh", asinhl, 0.5L, 4.81201171875000000000E-1L,
220 1.06531846034474977589E-5L, 8.94427190999915878564E-1L, TOL},
221 {"asinh", asinhl, 1.0L, 8.81362915039062500000E-1L,
222 1.06719804805252326093E-5L, 7.07106781186547524401E-1L, TOL},
223 {"asinh", asinhl, 2.0L, 1.44363403320312500000E0L,
224 1.44197568534249327674E-6L, 4.47213595499957939282E-1L, TOL},
225 {"acosh", acoshl, 2.0L, 1.31695556640625000000E0L,
226 2.33051856670862504635E-6L, 5.77350269189625764509E-1L, TOL},
227 {"acosh", acoshl, 1.5L, 9.62417602539062500000E-1L,
228 6.04758014439499551783E-6L, 8.94427190999915878564E-1L, TOL},
229 {"acosh", acoshl, 1.03125L, 2.49343872070312500000E-1L,
230 9.62177257298785143908E-6L, 3.96911150685467059809E0L, TOL},
231 {"atanh", atanhl, 0.5L, 5.49301147460937500000E-1L,
232 4.99687311734569762262E-6L, 1.33333333333333333333E0L, TOL},
233
234 #if 0
235 {"j0", j0l, 8.0L, 1.71646118164062500000E-1L,
236 4.68897349140609086941E-6L, -2.34636346853914624381E-1, -4},
237 {"j0", j0l, 4.54541015625L, -3.09783935546875000000E-1L,
238 7.07472668157686463367E-6L, 2.42993657373627558460E-1L, -4},
239 {"j0", j0l, 2.85711669921875L, -2.07901000976562500000E-1L,
240 1.15237285263902751582E-5L, -3.90402225324501311651E-1L, -4},
241 {"j0", j0l, 2.0L, 2.23876953125000000000E-1L,
242 1.38260162356680518275E-5L, -5.76724807756873387202E-1L, -4},
243 {"j0", j0l, 1.16415321826934814453125e-10L, 9.99984741210937500000E-1L,
244 1.52587890624999966119E-5L, 9.99999999999999999997E-1L, -4},
245 {"j0", j0l, -2.0L, 2.23876953125000000000E-1L,
246 1.38260162356680518275E-5L, 5.76724807756873387202E-1L, -4},
247 {"y0", y0l, 8.0L, 2.23510742187500000000E-1L,
248 1.07472000662205273234E-5L, 1.58060461731247494256E-1L, -4},
249 {"y0", y0l, 4.54541015625L, -2.08114624023437500000E-1L,
250 1.45018823856668874574E-5L, -2.88887645307401250876E-1L, -4},
251 {"y0", y0l, 2.85711669921875L, 4.20303344726562500000E-1L,
252 1.32781607563122276008E-5L, -2.82488638474982469213E-1, -4},
253 {"y0", y0l, 2.0L, 5.10360717773437500000E-1L,
254 1.49548763076195966066E-5L, 1.07032431540937546888E-1L, -4},
255 {"y0", y0l, 1.16415321826934814453125e-10L, -1.46357574462890625000E1L,
256 3.54110537011061127637E-6L, 5.46852220461145271913E9L, -4},
257 {"j1", j1l, 8.0L, 2.34634399414062500000E-1L,
258 1.94743985212438127665E-6L,1.42321263780814578043E-1, -4},
259 {"j1", j1l, 4.54541015625L, -2.42996215820312500000E-1L,
260 2.55844668494153980076E-6L, -2.56317734136211337012E-1, -4},
261 {"j1", j1l, 2.85711669921875L, 3.90396118164062500000E-1L,
262 6.10716043881165077013E-6L, -3.44531507106757980441E-1L, -4},
263 {"j1", j1l, 2.0L, 5.76721191406250000000E-1L,
264 3.61635062338720244824E-6L, -6.44716247372010255494E-2L, -4},
265 {"j1", j1l, 1.16415321826934814453125e-10L,
266 5.820677273504770710133016109466552734375e-11L,
267 8.881784197001251337312921818461805735896e-16L,
268 4.99999999999999999997E-1L, -4},
269 {"j1", j1l, -2.0L, -5.76721191406250000000E-1L,
270 -3.61635062338720244824E-6L, -6.44716247372010255494E-2L, -4},
271 {"y1", y1l, 8.0L, -1.58065795898437500000E-1L,
272 5.33416719000574444473E-6L, 2.43279047103972157309E-1L, -4},
273 {"y1", y1l, 4.54541015625L, 2.88879394531250000000E-1L,
274 8.25077615125087585195E-6L, -2.71656024771791736625E-1L, -4},
275 {"y1", y1l, 2.85711669921875L, 2.82485961914062500000E-1,
276 2.67656091996921314433E-6L, 3.21444694221532719737E-1, -4},
277 {"y1", y1l, 2.0L, -1.07040405273437500000E-1L,
278 7.97373249995311162923E-6L, 5.63891888420213893041E-1, -4},
279 {"y1", y1l, 1.16415321826934814453125e-10L, -5.46852220500000000000E9L,
280 3.88547280871200700671E-1L, 4.69742480525120196168E19L, -4},
281 #endif
282
283 {"tgamma", tgammal, 1.0L, 1.0L,
284 0.0L, -5.772156649015328606e-1L, TOL},
285 {"tgamma", tgammal, 2.0L, 1.0L,
286 0.0L, 4.2278433509846713939e-1L, TOL},
287 {"tgamma", tgammal, 3.0L, 2.0L,
288 0.0L, 1.845568670196934279L, TOL},
289 {"tgamma", tgammal, 4.0L, 6.0L,
290 0.0L, 7.536706010590802836L, TOL},
291
292 {"lgamma", lgammal, 8.0L, 8.525146484375L,
293 1.48766904143001655310E-5, 2.01564147795560999654E0L, TOL},
294 {"lgamma", lgammal, 8.99993896484375e-1L, 6.6375732421875e-2L,
295 5.11505711292524166220E-6L, -7.54938684259372234258E-1, -TOL},
296 {"lgamma", lgammal, 7.31597900390625e-1L, 2.2369384765625e-1L,
297 5.21506341809849792422E-6L,-1.13355566660398608343E0L, -TOL},
298 {"lgamma", lgammal, 2.31639862060546875e-1L, 1.3686676025390625L,
299 1.12609441752996145670E-5L, -4.56670961813812679012E0, -TOL},
300 {"lgamma", lgammal, 1.73162841796875L, -8.88214111328125e-2L,
301 3.36207740803753034508E-6L, 2.33339034686200586920E-1L, -TOL},
302 {"lgamma", lgammal, 1.23162841796875L,-9.3902587890625e-2L,
303 1.28765089229009648104E-5L, -2.49677345775751390414E-1L, -TOL},
304 {"lgamma", lgammal, 7.3786976294838206464e19L, 3.301798506038663053312e21L,
305 -1.656137564136932662487046269677E5L, 4.57477139169563904215E1L, TOL},
306 {"lgamma", lgammal, 1.0L, 0.0L,
307 0.0L, -5.77215664901532860607E-1L, -TOL},
308 {"lgamma", lgammal, 2.0L, 0.0L,
309 0.0L, 4.22784335098467139393E-1L, -TOL},
310 {"lgamma", lgammal, 1.08420217248550443401E-19L,4.36682586669921875e1L,
311 1.37082843669932230418E-5L, -9.22337203685477580858E18L, TOL},
312 {"lgamma", lgammal, -0.5L, 1.2655029296875L,
313 9.19379714539648894580E-6L, 3.64899739785765205590E-2L, TOL},
314 {"lgamma", lgammal, -1.5L, 8.6004638671875e-1L,
315 6.28657731014510932682E-7L, 7.03156640645243187226E-1L, TOL},
316 {"lgamma", lgammal, -2.5L, -5.6243896484375E-2L,
317 1.79986700949327405470E-7, 1.10315664064524318723E0L, -TOL},
318 {"lgamma", lgammal, -3.5L, -1.30902099609375L,
319 1.43111007079536392848E-5L, 1.38887092635952890151E0L, TOL},
320
321 {"null", NULL, 0.0L, 0.0L, 0.0L, 1},
322 };
323
324 /* These take care of extra-precise floating point register problems. */
325 static volatile long double volat1;
326 static volatile long double volat2;
327
328
329 /* Return the next nearest floating point value to X
330 in the direction of UPDOWN (+1 or -1).
331 (Might fail if X is denormalized.) */
332
333 static long double
nextval(x,updown)334 nextval (x, updown)
335 long double x;
336 int updown;
337 {
338 long double m;
339 int i;
340
341 volat1 = x;
342 m = 0.25L * MACHEPL * volat1 * updown;
343 volat2 = volat1 + m;
344 if (volat2 != volat1)
345 printf ("successor failed\n");
346
347 for (i = 2; i < 10; i++)
348 {
349 volat2 = volat1 + i * m;
350 if (volat1 != volat2)
351 return volat2;
352 }
353
354 printf ("nextval failed\n");
355 return volat1;
356 }
357
358
359
360
361 int
monotl()362 monotl ()
363 {
364 long double (*fun1) (long double);
365 int i, j, errs, tests, err_thresh;
366 long double x, x0, dy, err;
367
368 errs = 0;
369 tests = 0;
370 i = 0;
371
372 for (;;)
373 {
374 /* Function call reference. */
375 fun1 = test1[i].func;
376 if (fun1 == NULL)
377 break;
378 /* Function argument. */
379 volat1 = test1[i].arg1;
380 /* x0 is the given argument, x scans from slightly below to above x0. */
381 x0 = volat1;
382 x = volat1;
383 for (j = 0; j <= NPTS; j++)
384 {
385 /* delta x */
386 volat1 = x - x0;
387 /* delta y */
388 dy = volat1 * test1[i].derivative;
389 /* y + delta y */
390 dy = test1[i].answer2 + dy;
391 volat1 = test1[i].answer1 + dy;
392 /* Run the function under test. */
393 volat2 = (*(fun1)) (x);
394 if (volat2 != volat1)
395 {
396 /* Estimate difference between program result
397 and extended precision function value. */
398 err = volat2 - test1[i].answer1;
399 err = err - dy;
400 /* Compare difference with reporting threshold. */
401 err_thresh = test1[i].thresh;
402 if (err_thresh >= 0)
403 err = err / volat1; /* relative error */
404 else
405 {
406 err_thresh = -err_thresh; /* absolute error */
407 /* ...but relative error if function value > 1 */
408 if (fabsl(volat1) > 1.0L)
409 err = err / volat1;
410 }
411 if (fabsl (err) > (err_thresh * MACHEPL))
412 {
413 printf ("%d %s(%.19Le) = %.19Le, rel err = %.3Le\n",
414 j, test1[i].name, x, volat2, err);
415 errs += 1;
416 }
417 }
418 x = nextval (x, 1);
419 tests += 1;
420 }
421
422 x = x0;
423 x = nextval (x, -1);
424 for (j = 1; j < NPTS; j++)
425 {
426 volat1 = x - x0;
427 dy = volat1 * test1[i].derivative;
428 dy = test1[i].answer2 + dy;
429 volat1 = test1[i].answer1 + dy;
430 volat2 = (*(fun1)) (x);
431 if (volat2 != volat1)
432 {
433 err = volat2 - test1[i].answer1;
434 err = err - dy;
435 err_thresh = test1[i].thresh;
436 if (err_thresh >= 0)
437 err = err / volat1; /* relative error */
438 else
439 {
440 err_thresh = -err_thresh;
441 if (fabsl(volat1) > 1.0L)
442 err = err / volat1;
443 }
444 if (fabsl (err) > (err_thresh * MACHEPL))
445 {
446 printf ("%d %s(%.19Le) = %.19Le, rel err = %.3Le\n",
447 j, test1[i].name, x, volat2, err);
448 errs += 1;
449 }
450 }
451 x = nextval (x, -1);
452 tests += 1;
453 }
454 i += 1;
455 }
456 printf ("%d errors in %d tests\n", errs, tests);
457 return (errs);
458 }
459 #endif /* LDBL_MANT_DIG == 64 */
460