1
1
/*
2
- * Copyright (c) 2011, 2022 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2011, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
23
23
24
24
/*
25
25
* @test
26
- * @bug 4900206
26
+ * @bug 4900206 8316708
27
27
* @summary Test worst case behavior of exp, log, sin, cos, etc.
28
28
* @build Tests
29
29
* @build WorstCaseTests
32
32
*/
33
33
34
34
/**
35
- * Use "Table Maker's Dilemma" results from Jean-Michel Muller and
36
- * Vincent Lefèvre, to test the math library. See
37
- * http://perso.ens-lyon.fr/jean-michel.muller/TMD.html for original
35
+ * This test contains two distinct kinds of worst-case inputs:
36
+ *
37
+ * 1) Exact numerical results that are nearly half-way between
38
+ * representable numbers or very close to a representable
39
+ * number. (Half-way cases are hardest for round to nearest even;
40
+ * close to a representable number cases are hard for directed
41
+ * roundings.)
42
+ *
43
+ * 2) Worst-case errors as observed empirically across different
44
+ * implementations that are not correctly rounded.
45
+ *
46
+ * For the first category, the "Table Maker's Dilemma" results from
47
+ * Jean-Michel Muller and Vincent Lefèvre, are used.
48
+ * See https://perso.ens-lyon.fr/jean-michel.muller/TMD.html for original
38
49
* test vectors from 2000 and see
39
- * http ://perso.ens-lyon.fr/jean-michel.muller/TMDworstcases.pdf with
50
+ * https ://perso.ens-lyon.fr/jean-michel.muller/TMDworstcases.pdf with
40
51
* additional test vectors from 2003. The latter link also contains
41
52
* some information about the methodology used to produce the test
42
53
* vectors.
52
63
* JDK implementation complies with a 1 ulp bound on the worst-case
53
64
* values. Therefore, no addition leeway is afforded when testing
54
65
* sinh and cosh.
66
+ *
67
+ * For the second category, worst-case observed error inputs for the
68
+ * FDLIBM-derived OpenLibm 0.8.1 and other math libraries are added
69
+ * from "Accuracy of Mathematical Functions in Single, Double, Double
70
+ * Extended, and Quadruple Precision" by Brian Gladman, Vincenzo
71
+ * Innocente and Paul Zimmermann.
72
+ *
73
+ * From https://openlibm.org/, "The OpenLibm code derives from the
74
+ * FreeBSD msun and OpenBSD libm implementations, which in turn derive
75
+ * from FDLIBM 5.3." Java's StrictMath libraries use the FDLIBM 5.3
76
+ * algorithms.
55
77
*/
56
78
public class WorstCaseTests {
57
79
private WorstCaseTests () {throw new AssertionError ("No instances for you." );}
@@ -77,6 +99,9 @@ public static void main(String... args) {
77
99
}
78
100
}
79
101
102
+ /*
103
+ * 1 ulp stated error bound
104
+ */
80
105
private static int testWorstExp () {
81
106
int failures = 0 ;
82
107
double [][] testCases = {
@@ -113,6 +138,17 @@ private static int testWorstExp() {
113
138
{+0x1.A8EAD058BC6B8p3 , 0x1.1D71965F516ADp19 },
114
139
{+0x1.1D5C2DAEBE367p4 , 0x1.A8C02E974C314p25 },
115
140
{+0x1.C44CE0D716A1Ap4 , 0x1.B890CA8637AE1p40 },
141
+
142
+ // Worst-case observed error for OpenLibm
143
+ {+0x1.2e8f20cf3cbe7p+8 , 0x1.6a2a59cc78bf7p436 },
144
+ // Other worst-case observed errors
145
+ {-0x1.49f33ad2c1c58p+9 , 0x1.f3ccc815431b5p-953 },
146
+ {+0x1.fce66609f7428p+5 , 0x1.b59724cb0bc4cp91 },
147
+ {+0x1.b97dc8345c55p+5 , 0x1.88ab482dafdd7p79 },
148
+ {-0x1.18209ecd19a8cp+6 , 0x1.f3dcee4c90df9p-102 },
149
+ {-0x1.4133f4fd79c1cp-13 , 0x1.ffebed256fadp-1 },
150
+ {-0x1.74046dfefd9d1p+9 , 0x0.0000000000001p-1022 },
151
+ {-0x1.49f33ad2c1c58p+9 , 0x1.f3ccc815431b5p-953 },
116
152
};
117
153
118
154
for (double [] testCase : testCases ) {
@@ -130,6 +166,9 @@ private static int testExpCase(double input, double expected) {
130
166
return failures ;
131
167
}
132
168
169
+ /*
170
+ * 1 ulp stated error bound
171
+ */
133
172
private static int testWorstLog () {
134
173
int failures = 0 ;
135
174
double [][] testCases = {
@@ -145,6 +184,19 @@ private static int testWorstLog() {
145
184
{+0x17.F3825778AAAFp0 , +0x3.2D0F907F5E00Cp+0 },
146
185
{+0x1AC.50B409C8AEEp0 , +0x6.0F52F37AECFCCp+0 },
147
186
{+0x1.DE7CD6751029Ap16 , +0x1.76E7E5D7B6EABp+3 },
187
+
188
+ // Worst-case observed error for OpenLibm
189
+ {+0x1.48ae5a67204f5p+0 , 0x1.ffd10abffc3fep-3 },
190
+ // Other worst-case observed errors
191
+ {+0x1.1211bef8f68e9p+0 , +0x1.175caeca67f84p-4 },
192
+ {+0x1.008000db2e8bep+0 , +0x1.ff83959f5cc1fp-10 },
193
+ {+0x1.0ffea3878db6bp+0 , +0x1.f07a0cca521efp-5 },
194
+ {+0x1.dc0b586f2b26p-1 , -0x1.2a3eaaa6e8d72p-4 },
195
+ {+0x1.490af72a25a81p-1 , -0x1.c4bf7ae48f078p-2 },
196
+ {+0x1.5b6e7e4e96f86p+2 , +0x1.b11240cba290dp0 },
197
+ {+0x1.0ffc349469a2fp+0 , +0x1.f030c2507cd81p-5 },
198
+ {+0x1.69e7aa6da2df5p-1 , -0x1.634508c9adfp-2 },
199
+ {+0x1.5556123e8a2bp-1 , -0x1.9f300810f7d7cp-2 },
148
200
};
149
201
150
202
for (double [] testCase : testCases ) {
@@ -162,6 +214,9 @@ private static int testLogCase(double input, double expected) {
162
214
return failures ;
163
215
}
164
216
217
+ /*
218
+ * 1 ulp stated error bound
219
+ */
165
220
private static int testWorstSin () {
166
221
int failures = 0 ;
167
222
double [][] testCases = {
@@ -178,6 +233,19 @@ private static int testWorstSin() {
178
233
{+0x1.921FB54442D18p-0 , +0x1.FFFFFFFFFFFFFp-1 },
179
234
180
235
{+0x1.6756745770A51p+1 , +0x1.4FF350E412821p-2 },
236
+
237
+ // Worst-case observed error for OpenLibm
238
+ {+0x1.4d84db080b9fdp+21 , +0x1.6e21c4ff6aec3p-1 },
239
+ // Other worst-case observed errors
240
+ {-0x1.f8b791cafcdefp+4 , -0x1.073ca87470df9p-3 },
241
+ {-0x1.0e16eb809a35dp+944 , +0x1.b5e361ed01dacp-2 },
242
+ {-0x1.85e624577c23ep-1 , -0x1.614ac15b6df5ap-1 },
243
+ {-0x1.842d8ec8f752fp+21 , -0x1.6ce864edeaffdp-1 },
244
+ {-0x1.07e4c92b5349dp+4 , +0x1.6a096375ffb23p-1 },
245
+ {-0x1.13a5ccd87c9bbp+1008 , -0x1.27b3964185d8dp-1 },
246
+ {-0x1.11b624b546894p+9 , -0x1.6a35f2416aba8p-1 },
247
+ {-0x1.1c49ad613ff3bp+19 , -0x1.fffe203cfabe1p-2 },
248
+ {-0x1.f05e952d81b89p+5 , +0x1.6a2319a85a544p-1 },
181
249
};
182
250
183
251
for (double [] testCase : testCases ) {
@@ -195,6 +263,9 @@ private static int testSinCase(double input, double expected) {
195
263
return failures ;
196
264
}
197
265
266
+ /*
267
+ * 1 ulp stated error bound
268
+ */
198
269
private static int testWorstAsin () {
199
270
int failures = 0 ;
200
271
double [][] testCases = {
@@ -210,6 +281,18 @@ private static int testWorstAsin() {
210
281
{+0x1.1ED06D50F7E88p-1 , +0x1.30706F699466Dp-1 },
211
282
{+0x1.D5B05A89D3E77p-1 , +0x1.29517AB4C132Ap+0 },
212
283
{+0x1.E264357EA0E29p-1 , +0x1.3AA301F6EBB1Dp+0 },
284
+
285
+ // Worst-case observed error for OpenLibm
286
+ {-0x1.004d1c5a9400bp-1 , -0x1.0c6e322e8a28bp-1 },
287
+ // Other worst-case observed errors
288
+ {-0x1.0000045b2c904p-3 , -0x1.00abe5252746cp-3 },
289
+ {+0x1.6c042a6378102p-1 , +0x1.94eda53f72c5ap-1 },
290
+ {-0x1.00d44cccfa99p-1 , -0x1.0d0a6a0e79e15p-1 },
291
+ {+0x1.eae75e3d82b6fp-2 , +0x1.fff7d74b1ea4fp-2 },
292
+ {-0x1.0239000439deep-1 , -0x1.0ea71ea2a7cd7p-1 },
293
+ {+0x1.0479b37d95e5cp-1 , +0x1.1143fafdc5b2cp-1 },
294
+ {-0x1.2ef2481799c7cp-1 , -0x1.442d10aa50906p-1 },
295
+ {+0x1.df27e1c764802p-2 , +0x1.f2a0f0c96deefp-2 },
213
296
};
214
297
215
298
for (double [] testCase : testCases ) {
@@ -227,6 +310,9 @@ private static int testAsinCase(double input, double expected) {
227
310
return failures ;
228
311
}
229
312
313
+ /*
314
+ * 1 ulp stated error bound
315
+ */
230
316
private static int testWorstCos () {
231
317
int failures = 0 ;
232
318
double [][] testCases = {
@@ -243,6 +329,19 @@ private static int testWorstCos() {
243
329
{+0x1.7CB7648526F99p-1 , +0x1.78DAF01036D0Cp-1 },
244
330
{+0x1.C65A170474549p-1 , +0x1.434A3645BE208p-1 },
245
331
{+0x1.6B8A6273D7C21p+0 , +0x1.337FC5B072C52p-3 },
332
+
333
+ // Worst-case observed error for OpenLibm
334
+ {-0x1.34e729fd08086p+21 , +0x1.6a6a0d6a17f0fp-1 },
335
+ // Other worst-case observed errors
336
+ {-0x1.7120161c92674p+0 , +0x1.0741fb7683849p-3 },
337
+ {-0x1.d19ebc5567dcdp+311 , -0x1.b5d2f45f68958p-2 },
338
+ {+0x1.91e60af551108p-1 , +0x1.6a32aaa34b118p-1 },
339
+ {-0x1.4ae182c1ab422p+21 , -0x1.6c9c3831b6e3bp-1 },
340
+ {-0x1.34e729fd08086p+21 , +0x1.6a6a0d6a17f0fp-1 },
341
+ {+0x1.2f29eb4e99fa2p+7 , +0x1.6a0751dc5d2bbp-1 },
342
+ {-0x1.9200634d4471fp-1 , +0x1.6a200b493230cp-1 },
343
+ {+0x1.25133ca3904dfp+20 , -0x1.fb399cd6fe563p-3 },
344
+ {+0x1.2a33ae49ab15dp+1 , -0x1.60524e89bbcb2p-1 },
246
345
};
247
346
248
347
for (double [] testCase : testCases ) {
@@ -260,13 +359,28 @@ private static int testCosCase(double input, double expected) {
260
359
return failures ;
261
360
}
262
361
362
+ /*
363
+ * 1 ulp stated error bound
364
+ */
263
365
private static int testWorstAcos () {
264
366
int failures = 0 ;
265
367
double [][] testCases = {
266
368
{+0x1.FD737BE914578p-11 , +0x1.91E006D41D8D8p+0 },
267
369
{+0x1.4182199998587p-1 , +0x1.C8A538AE83D1Fp-1 },
268
370
{+0x1.E45A1C93651ECp-1 , +0x1.520DC553F6B23p-2 },
269
371
{+0x1.F10FC61E2C78Fp-1 , +0x1.EFEEF61D39AC1p-3 },
372
+
373
+ // Worst-case observed error for OpenLibm
374
+ {-0x1.0068b067c6feep-1 , +0x1.0c335e2f0726fp1 },
375
+ // Other worst-case observed errors
376
+ {+0x1.dffffb3488a4p-1 , 0x1.6bf3a4a4f4dcbp-2 },
377
+ {+0x1.6c05eb219ec46p-1 , 0x1.8f4f472807261p-1 },
378
+ {+0x1.35b03e336a82bp-1 , 0x1.d7a84ec2f6707p-1 },
379
+ {-0x1.8d313198a2e03p-53 , 0x1.921fb54442d19p0 },
380
+ {-0x1.010fd0ad6aa41p-1 , 0x1.0c63a8cd23beep1 },
381
+ {+0x1.251869c3f7881p-1 , 0x1.ec2ff0c102683p-1 },
382
+ {+0x1.266637a3d2bbcp-1 , 0x1.ea98637533648p-1 },
383
+ {-0x1.36b1482765f6dp-1 , 0x1.1c8666ca1cab1p1 },
270
384
};
271
385
272
386
for (double [] testCase : testCases ) {
@@ -284,6 +398,9 @@ private static int testAcosCase(double input, double expected) {
284
398
return failures ;
285
399
}
286
400
401
+ /*
402
+ * 1.25 ulp stated error bound
403
+ */
287
404
private static int testWorstTan () {
288
405
int failures = 0 ;
289
406
double [][] testCases = {
@@ -296,6 +413,9 @@ private static int testWorstTan() {
296
413
{+0x1.D696BFA988DB9p-2 , +0x1.FAC71CD34EEA6p-2 },
297
414
{+0x1.46AC372243536p-1 , +0x1.7BA49F739829Ep-1 },
298
415
{+0x0.A3561B9121A9Bp+0 , +0x0.BDD24FB9CC14Fp+0 },
416
+
417
+ // Worst-case observed error for OpenLibm, outside of 1 ulp error
418
+ // {0x1.3f9605aaeb51bp+21, -0x1.9678ee5d64934p-1}, // 1.02
299
419
};
300
420
301
421
for (double [] testCase : testCases ) {
@@ -313,6 +433,9 @@ private static int testTanCase(double input, double expected) {
313
433
return failures ;
314
434
}
315
435
436
+ /*
437
+ * 1 ulp stated error bound
438
+ */
316
439
private static int testWorstAtan () {
317
440
int failures = 0 ;
318
441
double [][] testCases = {
@@ -328,6 +451,19 @@ private static int testWorstAtan() {
328
451
{+0x1.7BA49F739829Fp-1 , +0x1.46AC372243536p-1 },
329
452
330
453
{+0x0.BDD24FB9CC14F8p+0 , +0x0.A3561B9121A9Bp+0 },
454
+
455
+ // Worst-case observed error
456
+ {0x1.62ff6a1682c25p-1 , +0x1.3666b15c8756ap-1 },
457
+ // Other worst-case observed errors
458
+ {+0x1.f9004c4fef9eap-4 , 0x1.f67727f5618f2p-4 },
459
+ {-0x1.ffff8020d3d1dp-7 , -0x1.fff4d5e4886c7p-7 },
460
+ {+0x1.0103fc4ebaaa8p+1 , 0x1.1bd5c375c97b5p0 },
461
+ {+0x1.01e0be37af68fp+1 , 0x1.1c2d45ec82765p0 },
462
+ {-0x1.60370d15396b7p-1 , -0x1.348461c347fd9p-1 },
463
+ {+0x1.032b4811f3dc5p+0 , 0x1.9545fd233ee14p-1 },
464
+ {+0x1.52184b1b9bd9bp+0 , 0x1.d86de33c93814p-1 },
465
+ {-0x1.0684fa9fa7481p+0 , -0x1.988f9da70b11ap-1 },
466
+
331
467
};
332
468
333
469
for (double [] testCase : testCases ) {
@@ -345,6 +481,9 @@ private static int testAtanCase(double input, double expected) {
345
481
return failures ;
346
482
}
347
483
484
+ /*
485
+ * 1 ulp stated error bound
486
+ */
348
487
private static int testWorstPow2 () {
349
488
int failures = 0 ;
350
489
double [][] testCases = {
0 commit comments