annotate tests/test-ceilf2.c @ 9335:5f9727c11975

Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
author Bruno Haible <bruno@clisp.org>
date Sat, 13 Oct 2007 03:09:19 +0200
parents
children 4e720cd88140
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9335
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Test of rounding towards positive infinity.
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2 Copyright (C) 2007 Free Software Foundation, Inc.
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 (at your option) any later version.
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #include <config.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include <math.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <float.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <stdbool.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <stdint.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <stdio.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdlib.h>
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #include "isnanf.h"
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #define ASSERT(expr) \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 do \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 { \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 if (!(expr)) \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 { \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 abort (); \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 } \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 } \
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 while (0)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 /* The reference implementation, taken from lib/ceil.c. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 #define DOUBLE float
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 #define MANT_DIG FLT_MANT_DIG
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 #define L_(literal) literal##f
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 /* 2^(MANT_DIG-1). */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 static const DOUBLE TWO_MANT_DIG =
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 /* Assume MANT_DIG <= 5 * 31.
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 Use the identity
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 n = floor(n/5) + floor((n+1)/5) + ... + floor((n+4)/5). */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 (DOUBLE) (1U << ((MANT_DIG - 1) / 5))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 * (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 * (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 * (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5));
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 DOUBLE
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 ceilf_reference (DOUBLE x)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 /* The use of 'volatile' guarantees that excess precision bits are dropped
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 at each addition step and before the following comparison at the caller's
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 site. It is necessary on x86 systems where double-floats are not IEEE
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 compliant by default, to avoid that the results become platform and compiler
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 option dependent. 'volatile' is a portable alternative to gcc's
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 -ffloat-store option. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 volatile DOUBLE y = x;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 volatile DOUBLE z = y;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 if (z > L_(0.0))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 /* Avoid rounding errors for values near 2^k, where k >= MANT_DIG-1. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 if (z < TWO_MANT_DIG)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 /* Round to the next integer (nearest or up or down, doesn't matter). */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 z += TWO_MANT_DIG;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 z -= TWO_MANT_DIG;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 /* Enforce rounding up. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 if (z < y)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 z += L_(1.0);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 else if (z < L_(0.0))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 /* Avoid rounding errors for values near -2^k, where k >= MANT_DIG-1. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 if (z > - TWO_MANT_DIG)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 /* Round to the next integer (nearest or up or down, doesn't matter). */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 z -= TWO_MANT_DIG;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 z += TWO_MANT_DIG;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 /* Enforce rounding up. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 if (z < y)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 z += L_(1.0);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 return z;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 /* Test for equality. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 static int
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 equal (DOUBLE x, DOUBLE y)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 return (isnanf (x) ? isnanf (y) : x == y);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 /* Test whether the result for a given argument is correct. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 static bool
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 correct_result_p (DOUBLE x, DOUBLE result)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 return
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 (x > 0 && x <= 1 ? result == L_(1.0) :
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 x + 1 > x ? result >= x && result < x + 1 :
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 equal (result, x));
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119 /* Test the function for a given argument. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 static int
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 check (float x)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 /* If the reference implementation is incorrect, bail out immediately. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 float reference = ceilf_reference (x);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 ASSERT (correct_result_p (x, reference));
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 /* If the actual implementation is wrong, return an error code. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 float result = ceilf (x);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 if (correct_result_p (x, result))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 return 0;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 else
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 fprintf (stderr, "ceilf %g(%a) = %g(%a) or %g(%a)?\n",
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 x, x, reference, reference, result, result);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 return 1;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 #define NUM_HIGHBITS 12
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 #define NUM_LOWBITS 4
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 int
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 main ()
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 unsigned int highbits;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147 unsigned int lowbits;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148 int error = 0;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149 for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 {
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
152 /* Combine highbits and lowbits into a floating-point number,
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
153 sign-extending the lowbits to 32-NUM_HIGHBITS bits. */
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154 union { float f; uint32_t i; } janus;
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155 janus.i = ((uint32_t) highbits << (32 - NUM_HIGHBITS))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 | ((uint32_t) ((int32_t) ((uint32_t) lowbits << (32 - NUM_LOWBITS))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 >> (32 - NUM_LOWBITS - NUM_HIGHBITS))
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158 >> NUM_HIGHBITS);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 error |= check (janus.f);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 }
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 return (error ? 1 : 0);
5f9727c11975 Fix incorrect rounding of ceil, ceilf, ceill in some cases. Add new test.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 }