author | lbourges |
Sat, 09 Jan 2016 14:04:32 +0100 | |
changeset 35665 | e90002447fd5 |
parent 34417 | 57a3863abbb4 |
permissions | -rw-r--r-- |
34417 | 1 |
/* |
35665
e90002447fd5
8146076: Fail of sun/java2d/marlin/CeilAndFloorTests.java with Jigsaw
lbourges
parents:
34417
diff
changeset
|
2 |
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. |
34417 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 |
* or visit www.oracle.com if you need additional information or have any |
|
21 |
* questions. |
|
22 |
*/ |
|
23 |
||
24 |
import sun.java2d.marlin.FloatMath; |
|
25 |
||
26 |
/* |
|
27 |
* @test |
|
28 |
* @summary Check for correct implementation of FloatMath.ceil/floor |
|
29 |
* @run main CeilAndFloorTests |
|
35665
e90002447fd5
8146076: Fail of sun/java2d/marlin/CeilAndFloorTests.java with Jigsaw
lbourges
parents:
34417
diff
changeset
|
30 |
* @modules java.desktop/sun.java2d.marlin |
34417 | 31 |
*/ |
32 |
public class CeilAndFloorTests { |
|
33 |
||
34 |
public static String toHexString(float f) { |
|
35 |
if (!Float.isNaN(f)) |
|
36 |
return Float.toHexString(f); |
|
37 |
else |
|
38 |
return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")"; |
|
39 |
} |
|
40 |
||
41 |
public static int test(String testName, float input, |
|
42 |
float result, float expected) { |
|
43 |
if (Float.compare(expected, result) != 0) { |
|
44 |
System.err.println("Failure for " + testName + ":\n" + |
|
45 |
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" + |
|
46 |
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + |
|
47 |
"\tgot " + result + "\t(" + toHexString(result) + ")."); |
|
48 |
return 1; |
|
49 |
} |
|
50 |
else |
|
51 |
return 0; |
|
52 |
} |
|
53 |
||
54 |
public static int test_skip_0(String testName, float input, |
|
55 |
float result, float expected) |
|
56 |
{ |
|
57 |
// floor_int does not distinguish +0f and -0f |
|
58 |
// but it is not critical for Marlin |
|
59 |
if (Float.compare(expected, result) != 0 && (expected != 0f)) |
|
60 |
{ |
|
61 |
System.err.println("Failure for " + testName + ":\n" + |
|
62 |
"\tFor input " + input + "\t(" + toHexString(input) + ")\n" + |
|
63 |
"\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + |
|
64 |
"\tgot " + result + "\t(" + toHexString(result) + ")."); |
|
65 |
return 1; |
|
66 |
} |
|
67 |
else |
|
68 |
return 0; |
|
69 |
} |
|
70 |
||
71 |
private static int testCeilCase(float input, float expected) { |
|
72 |
int failures = 0; |
|
73 |
// float result: |
|
74 |
failures += test("FloatMath.ceil_f", input, FloatMath.ceil_f(input), expected); |
|
75 |
// int result: |
|
76 |
failures += test("FloatMath.ceil_int", input, FloatMath.ceil_int(input), (int)expected); |
|
77 |
failures += test("FloatMath.ceil_f (int)", input, (int)FloatMath.ceil_f(input), (int)expected); |
|
78 |
return failures; |
|
79 |
} |
|
80 |
||
81 |
private static int testFloorCase(float input, float expected) { |
|
82 |
int failures = 0; |
|
83 |
// float result: |
|
84 |
failures += test ("FloatMath.floor_f", input, FloatMath.floor_f(input), expected); |
|
85 |
// ignore difference between +0f and -0f: |
|
86 |
failures += test_skip_0("FloatMath.floor_int", input, FloatMath.floor_int(input), (int)expected); |
|
87 |
failures += test_skip_0("FloatMath.floor_f (int)", input, (int)FloatMath.floor_f(input), (int)expected); |
|
88 |
return failures; |
|
89 |
} |
|
90 |
||
91 |
private static int nearIntegerTests() { |
|
92 |
int failures = 0; |
|
93 |
||
94 |
float [] fixedPoints = { |
|
95 |
-0.0f, |
|
96 |
0.0f, |
|
97 |
-1.0f, |
|
98 |
1.0f, |
|
99 |
-0x1.0p52f, |
|
100 |
0x1.0p52f, |
|
101 |
-Float.MAX_VALUE, |
|
102 |
Float.MAX_VALUE, |
|
103 |
Float.NEGATIVE_INFINITY, |
|
104 |
Float.POSITIVE_INFINITY, |
|
105 |
Float.NaN, |
|
106 |
}; |
|
107 |
||
108 |
for(float fixedPoint : fixedPoints) { |
|
109 |
failures += testCeilCase(fixedPoint, fixedPoint); |
|
110 |
failures += testFloorCase(fixedPoint, fixedPoint); |
|
111 |
} |
|
112 |
||
113 |
for(int i = Float.MIN_EXPONENT; i <= Float.MAX_EXPONENT; i++) { |
|
114 |
float powerOfTwo = Math.scalb(1.0f, i); |
|
115 |
float neighborDown = Math.nextDown(powerOfTwo); |
|
116 |
float neighborUp = Math.nextUp(powerOfTwo); |
|
117 |
||
118 |
if (i < 0) { |
|
119 |
failures += testCeilCase( powerOfTwo, 1.0f); |
|
120 |
failures += testCeilCase(-powerOfTwo, -0.0f); |
|
121 |
||
122 |
failures += testFloorCase( powerOfTwo, 0.0f); |
|
123 |
failures += testFloorCase(-powerOfTwo, -1.0f); |
|
124 |
||
125 |
failures += testCeilCase( neighborDown, 1.0f); |
|
126 |
failures += testCeilCase(-neighborDown, -0.0f); |
|
127 |
||
128 |
failures += testFloorCase( neighborUp, 0.0f); |
|
129 |
failures += testFloorCase(-neighborUp, -1.0f); |
|
130 |
} else { |
|
131 |
failures += testCeilCase(powerOfTwo, powerOfTwo); |
|
132 |
failures += testFloorCase(powerOfTwo, powerOfTwo); |
|
133 |
||
134 |
if (neighborDown==Math.rint(neighborDown)) { |
|
135 |
failures += testCeilCase( neighborDown, neighborDown); |
|
136 |
failures += testCeilCase(-neighborDown, -neighborDown); |
|
137 |
||
138 |
failures += testFloorCase( neighborDown, neighborDown); |
|
139 |
failures += testFloorCase(-neighborDown,-neighborDown); |
|
140 |
} else { |
|
141 |
failures += testCeilCase( neighborDown, powerOfTwo); |
|
142 |
failures += testFloorCase(-neighborDown, -powerOfTwo); |
|
143 |
} |
|
144 |
||
145 |
if (neighborUp==Math.rint(neighborUp)) { |
|
146 |
failures += testCeilCase(neighborUp, neighborUp); |
|
147 |
failures += testCeilCase(-neighborUp, -neighborUp); |
|
148 |
||
149 |
failures += testFloorCase(neighborUp, neighborUp); |
|
150 |
failures += testFloorCase(-neighborUp, -neighborUp); |
|
151 |
} else { |
|
152 |
failures += testFloorCase(neighborUp, powerOfTwo); |
|
153 |
failures += testCeilCase(-neighborUp, -powerOfTwo); |
|
154 |
} |
|
155 |
} |
|
156 |
} |
|
157 |
||
158 |
for(int i = -(0x10000); i <= 0x10000; i++) { |
|
159 |
float f = (float) i; |
|
160 |
float neighborDown = Math.nextDown(f); |
|
161 |
float neighborUp = Math.nextUp(f); |
|
162 |
||
163 |
failures += testCeilCase( f, f); |
|
164 |
failures += testCeilCase(-f, -f); |
|
165 |
||
166 |
failures += testFloorCase( f, f); |
|
167 |
failures += testFloorCase(-f, -f); |
|
168 |
||
169 |
if (Math.abs(f) > 1.0) { |
|
170 |
failures += testCeilCase( neighborDown, f); |
|
171 |
failures += testCeilCase(-neighborDown, -f+1); |
|
172 |
||
173 |
failures += testFloorCase( neighborUp, f); |
|
174 |
failures += testFloorCase(-neighborUp, -f-1); |
|
175 |
} |
|
176 |
} |
|
177 |
||
178 |
return failures; |
|
179 |
} |
|
180 |
||
181 |
public static int roundingTests() { |
|
182 |
int failures = 0; |
|
183 |
float [][] testCases = { |
|
184 |
{ Float.MIN_VALUE, 1.0f}, |
|
185 |
{-Float.MIN_VALUE, -0.0f}, |
|
186 |
{ Math.nextDown(Float.MIN_NORMAL), 1.0f}, |
|
187 |
{-Math.nextDown(Float.MIN_NORMAL), -0.0f}, |
|
188 |
{ Float.MIN_NORMAL, 1.0f}, |
|
189 |
{-Float.MIN_NORMAL, -0.0f}, |
|
190 |
||
191 |
{ 0.1f, 1.0f}, |
|
192 |
{-0.1f, -0.0f}, |
|
193 |
||
194 |
{ 0.5f, 1.0f}, |
|
195 |
{-0.5f, -0.0f}, |
|
196 |
||
197 |
{ 1.5f, 2.0f}, |
|
198 |
{-1.5f, -1.0f}, |
|
199 |
||
200 |
{ 2.5f, 3.0f}, |
|
201 |
{-2.5f, -2.0f}, |
|
202 |
||
203 |
{ 12.3456789f, 13.0f}, |
|
204 |
{-12.3456789f, -12.0f}, |
|
205 |
||
206 |
{ Math.nextDown(1.0f), 1.0f}, |
|
207 |
{ Math.nextDown(-1.0f), -1.0f}, |
|
208 |
||
209 |
{ Math.nextUp(1.0f), 2.0f}, |
|
210 |
{ Math.nextUp(-1.0f), -0.0f}, |
|
211 |
||
212 |
{ 0x1.0p22f, 0x1.0p22f}, |
|
213 |
{-0x1.0p22f, -0x1.0p22f}, |
|
214 |
||
215 |
{ Math.nextDown(0x1.0p22f), 0x1.0p22f}, |
|
216 |
{-Math.nextUp(0x1.0p22f), -0x1.0p22f}, |
|
217 |
||
218 |
{ Math.nextUp(0x1.0p22f), 0x1.0p22f+1f}, |
|
219 |
{-Math.nextDown(0x1.0p22f), -0x1.0p22f+1f}, |
|
220 |
||
221 |
{ Math.nextDown(0x1.0p23f), 0x1.0p23f}, |
|
222 |
{-Math.nextUp(0x1.0p23f), -0x1.0p23f-1f}, |
|
223 |
||
224 |
{ Math.nextUp(0x1.0p23f), 0x1.0p23f+1f}, |
|
225 |
{-Math.nextDown(0x1.0p23f), -0x1.0p23f+1f}, |
|
226 |
}; |
|
227 |
||
228 |
for(float[] testCase : testCases) { |
|
229 |
failures += testCeilCase(testCase[0], testCase[1]); |
|
230 |
failures += testFloorCase(-testCase[0], -testCase[1]); |
|
231 |
} |
|
232 |
return failures; |
|
233 |
} |
|
234 |
||
235 |
public static void main(String... args) { |
|
236 |
int failures = 0; |
|
237 |
||
238 |
System.out.println("nearIntegerTests"); |
|
239 |
failures += nearIntegerTests(); |
|
240 |
||
241 |
System.out.println("roundingTests"); |
|
242 |
failures += roundingTests(); |
|
243 |
||
244 |
if (failures > 0) { |
|
245 |
System.err.println("Testing {FloatMath}.ceil/floor incurred " |
|
246 |
+ failures + " failures."); |
|
247 |
throw new RuntimeException(); |
|
248 |
} |
|
249 |
} |
|
250 |
} |