author | alanb |
Tue, 08 Feb 2011 19:31:44 +0000 | |
changeset 8189 | 5fd29d2cbc4b |
parent 7517 | 7303bc0e78d6 |
child 9266 | 121fb370f179 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
2 |
* Copyright (c) 2003, 2010 Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.misc; |
|
27 |
||
28 |
import sun.misc.FloatConsts; |
|
29 |
import sun.misc.DoubleConsts; |
|
30 |
||
31 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
32 |
* The class {@code FpUtils} contains static utility methods for |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
33 |
* manipulating and inspecting {@code float} and |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
34 |
* {@code double} floating-point numbers. These methods include |
2 | 35 |
* functionality recommended or required by the IEEE 754 |
36 |
* floating-point standard. |
|
37 |
* |
|
38 |
* @author Joseph D. Darcy |
|
39 |
*/ |
|
40 |
||
41 |
public class FpUtils { |
|
42 |
/* |
|
43 |
* The methods in this class are reasonably implemented using |
|
44 |
* direct or indirect bit-level manipulation of floating-point |
|
45 |
* values. However, having access to the IEEE 754 recommended |
|
46 |
* functions would obviate the need for most programmers to engage |
|
47 |
* in floating-point bit-twiddling. |
|
48 |
* |
|
49 |
* An IEEE 754 number has three fields, from most significant bit |
|
50 |
* to to least significant, sign, exponent, and significand. |
|
51 |
* |
|
52 |
* msb lsb |
|
53 |
* [sign|exponent| fractional_significand] |
|
54 |
* |
|
55 |
* Using some encoding cleverness, explained below, the high order |
|
56 |
* bit of the logical significand does not need to be explicitly |
|
57 |
* stored, thus "fractional_significand" instead of simply |
|
58 |
* "significand" in the figure above. |
|
59 |
* |
|
60 |
* For finite normal numbers, the numerical value encoded is |
|
61 |
* |
|
62 |
* (-1)^sign * 2^(exponent)*(1.fractional_significand) |
|
63 |
* |
|
64 |
* Most finite floating-point numbers are normalized; the exponent |
|
65 |
* value is reduced until the leading significand bit is 1. |
|
66 |
* Therefore, the leading 1 is redundant and is not explicitly |
|
67 |
* stored. If a numerical value is so small it cannot be |
|
68 |
* normalized, it has a subnormal representation. Subnormal |
|
69 |
* numbers don't have a leading 1 in their significand; subnormals |
|
70 |
* are encoding using a special exponent value. In other words, |
|
71 |
* the high-order bit of the logical significand can be elided in |
|
72 |
* from the representation in either case since the bit's value is |
|
73 |
* implicit from the exponent value. |
|
74 |
* |
|
75 |
* The exponent field uses a biased representation; if the bits of |
|
76 |
* the exponent are interpreted as a unsigned integer E, the |
|
77 |
* exponent represented is E - E_bias where E_bias depends on the |
|
78 |
* floating-point format. E can range between E_min and E_max, |
|
79 |
* constants which depend on the floating-point format. E_min and |
|
80 |
* E_max are -126 and +127 for float, -1022 and +1023 for double. |
|
81 |
* |
|
82 |
* The 32-bit float format has 1 sign bit, 8 exponent bits, and 23 |
|
83 |
* bits for the significand (which is logically 24 bits wide |
|
84 |
* because of the implicit bit). The 64-bit double format has 1 |
|
85 |
* sign bit, 11 exponent bits, and 52 bits for the significand |
|
86 |
* (logically 53 bits). |
|
87 |
* |
|
88 |
* Subnormal numbers and zero have the special exponent value |
|
89 |
* E_min -1; the numerical value represented by a subnormal is: |
|
90 |
* |
|
91 |
* (-1)^sign * 2^(E_min)*(0.fractional_significand) |
|
92 |
* |
|
93 |
* Zero is represented by all zero bits in the exponent and all |
|
94 |
* zero bits in the significand; zero can have either sign. |
|
95 |
* |
|
96 |
* Infinity and NaN are encoded using the exponent value E_max + |
|
97 |
* 1. Signed infinities have all significand bits zero; NaNs have |
|
98 |
* at least one non-zero significand bit. |
|
99 |
* |
|
100 |
* The details of IEEE 754 floating-point encoding will be used in |
|
101 |
* the methods below without further comment. For further |
|
102 |
* exposition on IEEE 754 numbers, see "IEEE Standard for Binary |
|
103 |
* Floating-Point Arithmetic" ANSI/IEEE Std 754-1985 or William |
|
104 |
* Kahan's "Lecture Notes on the Status of IEEE Standard 754 for |
|
105 |
* Binary Floating-Point Arithmetic", |
|
106 |
* http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps. |
|
107 |
* |
|
108 |
* Many of this class's methods are members of the set of IEEE 754 |
|
109 |
* recommended functions or similar functions recommended or |
|
110 |
* required by IEEE 754R. Discussion of various implementation |
|
111 |
* techniques for these functions have occurred in: |
|
112 |
* |
|
113 |
* W.J. Cody and Jerome T. Coonen, "Algorithm 772 Functions to |
|
114 |
* Support the IEEE Standard for Binary Floating-Point |
|
115 |
* Arithmetic," ACM Transactions on Mathematical Software, |
|
116 |
* vol. 19, no. 4, December 1993, pp. 443-451. |
|
117 |
* |
|
118 |
* Joseph D. Darcy, "Writing robust IEEE recommended functions in |
|
119 |
* ``100% Pure Java''(TM)," University of California, Berkeley |
|
120 |
* technical report UCB//CSD-98-1009. |
|
121 |
*/ |
|
122 |
||
123 |
/** |
|
124 |
* Don't let anyone instantiate this class. |
|
125 |
*/ |
|
126 |
private FpUtils() {} |
|
127 |
||
128 |
// Constants used in scalb |
|
129 |
static double twoToTheDoubleScaleUp = powerOfTwoD(512); |
|
130 |
static double twoToTheDoubleScaleDown = powerOfTwoD(-512); |
|
131 |
||
132 |
// Helper Methods |
|
133 |
||
134 |
// The following helper methods are used in the implementation of |
|
135 |
// the public recommended functions; they generally omit certain |
|
136 |
// tests for exception cases. |
|
137 |
||
138 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
139 |
* Returns unbiased exponent of a {@code double}. |
2 | 140 |
*/ |
141 |
public static int getExponent(double d){ |
|
142 |
/* |
|
143 |
* Bitwise convert d to long, mask out exponent bits, shift |
|
144 |
* to the right and then subtract out double's bias adjust to |
|
145 |
* get true exponent value. |
|
146 |
*/ |
|
147 |
return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >> |
|
148 |
(DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS); |
|
149 |
} |
|
150 |
||
151 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
152 |
* Returns unbiased exponent of a {@code float}. |
2 | 153 |
*/ |
154 |
public static int getExponent(float f){ |
|
155 |
/* |
|
156 |
* Bitwise convert f to integer, mask out exponent bits, shift |
|
157 |
* to the right and then subtract out float's bias adjust to |
|
158 |
* get true exponent value |
|
159 |
*/ |
|
160 |
return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >> |
|
161 |
(FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS; |
|
162 |
} |
|
163 |
||
164 |
/** |
|
165 |
* Returns a floating-point power of two in the normal range. |
|
166 |
*/ |
|
167 |
static double powerOfTwoD(int n) { |
|
168 |
assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT); |
|
169 |
return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) << |
|
170 |
(DoubleConsts.SIGNIFICAND_WIDTH-1)) |
|
171 |
& DoubleConsts.EXP_BIT_MASK); |
|
172 |
} |
|
173 |
||
174 |
/** |
|
175 |
* Returns a floating-point power of two in the normal range. |
|
176 |
*/ |
|
177 |
static float powerOfTwoF(int n) { |
|
178 |
assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT); |
|
179 |
return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) << |
|
180 |
(FloatConsts.SIGNIFICAND_WIDTH-1)) |
|
181 |
& FloatConsts.EXP_BIT_MASK); |
|
182 |
} |
|
183 |
||
184 |
/** |
|
185 |
* Returns the first floating-point argument with the sign of the |
|
186 |
* second floating-point argument. Note that unlike the {@link |
|
187 |
* FpUtils#copySign(double, double) copySign} method, this method |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
188 |
* does not require NaN {@code sign} arguments to be treated |
2 | 189 |
* as positive values; implementations are permitted to treat some |
190 |
* NaN arguments as positive and other NaN arguments as negative |
|
191 |
* to allow greater performance. |
|
192 |
* |
|
193 |
* @param magnitude the parameter providing the magnitude of the result |
|
194 |
* @param sign the parameter providing the sign of the result |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
195 |
* @return a value with the magnitude of {@code magnitude} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
196 |
* and the sign of {@code sign}. |
2 | 197 |
* @author Joseph D. Darcy |
198 |
*/ |
|
199 |
public static double rawCopySign(double magnitude, double sign) { |
|
200 |
return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) & |
|
201 |
(DoubleConsts.SIGN_BIT_MASK)) | |
|
202 |
(Double.doubleToRawLongBits(magnitude) & |
|
203 |
(DoubleConsts.EXP_BIT_MASK | |
|
204 |
DoubleConsts.SIGNIF_BIT_MASK))); |
|
205 |
} |
|
206 |
||
207 |
/** |
|
208 |
* Returns the first floating-point argument with the sign of the |
|
209 |
* second floating-point argument. Note that unlike the {@link |
|
210 |
* FpUtils#copySign(float, float) copySign} method, this method |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
211 |
* does not require NaN {@code sign} arguments to be treated |
2 | 212 |
* as positive values; implementations are permitted to treat some |
213 |
* NaN arguments as positive and other NaN arguments as negative |
|
214 |
* to allow greater performance. |
|
215 |
* |
|
216 |
* @param magnitude the parameter providing the magnitude of the result |
|
217 |
* @param sign the parameter providing the sign of the result |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
218 |
* @return a value with the magnitude of {@code magnitude} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
219 |
* and the sign of {@code sign}. |
2 | 220 |
* @author Joseph D. Darcy |
221 |
*/ |
|
222 |
public static float rawCopySign(float magnitude, float sign) { |
|
223 |
return Float.intBitsToFloat((Float.floatToRawIntBits(sign) & |
|
224 |
(FloatConsts.SIGN_BIT_MASK)) | |
|
225 |
(Float.floatToRawIntBits(magnitude) & |
|
226 |
(FloatConsts.EXP_BIT_MASK | |
|
227 |
FloatConsts.SIGNIF_BIT_MASK))); |
|
228 |
} |
|
229 |
||
230 |
/* ***************************************************************** */ |
|
231 |
||
232 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
233 |
* Returns {@code true} if the argument is a finite |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
234 |
* floating-point value; returns {@code false} otherwise (for |
2 | 235 |
* NaN and infinity arguments). |
236 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
237 |
* @param d the {@code double} value to be tested |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
238 |
* @return {@code true} if the argument is a finite |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
239 |
* floating-point value, {@code false} otherwise. |
2 | 240 |
*/ |
241 |
public static boolean isFinite(double d) { |
|
242 |
return Math.abs(d) <= DoubleConsts.MAX_VALUE; |
|
243 |
} |
|
244 |
||
245 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
246 |
* Returns {@code true} if the argument is a finite |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
247 |
* floating-point value; returns {@code false} otherwise (for |
2 | 248 |
* NaN and infinity arguments). |
249 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
250 |
* @param f the {@code float} value to be tested |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
251 |
* @return {@code true} if the argument is a finite |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
252 |
* floating-point value, {@code false} otherwise. |
2 | 253 |
*/ |
254 |
public static boolean isFinite(float f) { |
|
255 |
return Math.abs(f) <= FloatConsts.MAX_VALUE; |
|
256 |
} |
|
257 |
||
258 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
259 |
* Returns {@code true} if the specified number is infinitely |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
260 |
* large in magnitude, {@code false} otherwise. |
2 | 261 |
* |
262 |
* <p>Note that this method is equivalent to the {@link |
|
263 |
* Double#isInfinite(double) Double.isInfinite} method; the |
|
264 |
* functionality is included in this class for convenience. |
|
265 |
* |
|
266 |
* @param d the value to be tested. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
267 |
* @return {@code true} if the value of the argument is positive |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
268 |
* infinity or negative infinity; {@code false} otherwise. |
2 | 269 |
*/ |
270 |
public static boolean isInfinite(double d) { |
|
271 |
return Double.isInfinite(d); |
|
272 |
} |
|
273 |
||
274 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
275 |
* Returns {@code true} if the specified number is infinitely |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
276 |
* large in magnitude, {@code false} otherwise. |
2 | 277 |
* |
278 |
* <p>Note that this method is equivalent to the {@link |
|
279 |
* Float#isInfinite(float) Float.isInfinite} method; the |
|
280 |
* functionality is included in this class for convenience. |
|
281 |
* |
|
282 |
* @param f the value to be tested. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
283 |
* @return {@code true} if the argument is positive infinity or |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
284 |
* negative infinity; {@code false} otherwise. |
2 | 285 |
*/ |
286 |
public static boolean isInfinite(float f) { |
|
287 |
return Float.isInfinite(f); |
|
288 |
} |
|
289 |
||
290 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
291 |
* Returns {@code true} if the specified number is a |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
292 |
* Not-a-Number (NaN) value, {@code false} otherwise. |
2 | 293 |
* |
294 |
* <p>Note that this method is equivalent to the {@link |
|
295 |
* Double#isNaN(double) Double.isNaN} method; the functionality is |
|
296 |
* included in this class for convenience. |
|
297 |
* |
|
298 |
* @param d the value to be tested. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
299 |
* @return {@code true} if the value of the argument is NaN; |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
300 |
* {@code false} otherwise. |
2 | 301 |
*/ |
302 |
public static boolean isNaN(double d) { |
|
303 |
return Double.isNaN(d); |
|
304 |
} |
|
305 |
||
306 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
307 |
* Returns {@code true} if the specified number is a |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
308 |
* Not-a-Number (NaN) value, {@code false} otherwise. |
2 | 309 |
* |
310 |
* <p>Note that this method is equivalent to the {@link |
|
311 |
* Float#isNaN(float) Float.isNaN} method; the functionality is |
|
312 |
* included in this class for convenience. |
|
313 |
* |
|
314 |
* @param f the value to be tested. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
315 |
* @return {@code true} if the argument is NaN; |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
316 |
* {@code false} otherwise. |
2 | 317 |
*/ |
318 |
public static boolean isNaN(float f) { |
|
319 |
return Float.isNaN(f); |
|
320 |
} |
|
321 |
||
322 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
323 |
* Returns {@code true} if the unordered relation holds |
2 | 324 |
* between the two arguments. When two floating-point values are |
325 |
* unordered, one value is neither less than, equal to, nor |
|
326 |
* greater than the other. For the unordered relation to be true, |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
327 |
* at least one argument must be a {@code NaN}. |
2 | 328 |
* |
329 |
* @param arg1 the first argument |
|
330 |
* @param arg2 the second argument |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
331 |
* @return {@code true} if at least one argument is a NaN, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
332 |
* {@code false} otherwise. |
2 | 333 |
*/ |
334 |
public static boolean isUnordered(double arg1, double arg2) { |
|
335 |
return isNaN(arg1) || isNaN(arg2); |
|
336 |
} |
|
337 |
||
338 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
339 |
* Returns {@code true} if the unordered relation holds |
2 | 340 |
* between the two arguments. When two floating-point values are |
341 |
* unordered, one value is neither less than, equal to, nor |
|
342 |
* greater than the other. For the unordered relation to be true, |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
343 |
* at least one argument must be a {@code NaN}. |
2 | 344 |
* |
345 |
* @param arg1 the first argument |
|
346 |
* @param arg2 the second argument |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
347 |
* @return {@code true} if at least one argument is a NaN, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
348 |
* {@code false} otherwise. |
2 | 349 |
*/ |
350 |
public static boolean isUnordered(float arg1, float arg2) { |
|
351 |
return isNaN(arg1) || isNaN(arg2); |
|
352 |
} |
|
353 |
||
354 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
355 |
* Returns unbiased exponent of a {@code double}; for |
2 | 356 |
* subnormal values, the number is treated as if it were |
357 |
* normalized. That is for all finite, non-zero, positive numbers |
|
358 |
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is |
|
359 |
* always in the range [1, 2). |
|
360 |
* <p> |
|
361 |
* Special cases: |
|
362 |
* <ul> |
|
363 |
* <li> If the argument is NaN, then the result is 2<sup>30</sup>. |
|
364 |
* <li> If the argument is infinite, then the result is 2<sup>28</sup>. |
|
365 |
* <li> If the argument is zero, then the result is -(2<sup>28</sup>). |
|
366 |
* </ul> |
|
367 |
* |
|
368 |
* @param d floating-point number whose exponent is to be extracted |
|
369 |
* @return unbiased exponent of the argument. |
|
370 |
* @author Joseph D. Darcy |
|
371 |
*/ |
|
372 |
public static int ilogb(double d) { |
|
373 |
int exponent = getExponent(d); |
|
374 |
||
375 |
switch (exponent) { |
|
376 |
case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity |
|
377 |
if( isNaN(d) ) |
|
378 |
return (1<<30); // 2^30 |
|
379 |
else // infinite value |
|
380 |
return (1<<28); // 2^28 |
|
381 |
||
382 |
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal |
|
383 |
if(d == 0.0) { |
|
384 |
return -(1<<28); // -(2^28) |
|
385 |
} |
|
386 |
else { |
|
387 |
long transducer = Double.doubleToRawLongBits(d); |
|
388 |
||
389 |
/* |
|
390 |
* To avoid causing slow arithmetic on subnormals, |
|
391 |
* the scaling to determine when d's significand |
|
392 |
* is normalized is done in integer arithmetic. |
|
393 |
* (there must be at least one "1" bit in the |
|
394 |
* significand since zero has been screened out. |
|
395 |
*/ |
|
396 |
||
397 |
// isolate significand bits |
|
398 |
transducer &= DoubleConsts.SIGNIF_BIT_MASK; |
|
399 |
assert(transducer != 0L); |
|
400 |
||
401 |
// This loop is simple and functional. We might be |
|
402 |
// able to do something more clever that was faster; |
|
403 |
// e.g. number of leading zero detection on |
|
404 |
// (transducer << (# exponent and sign bits). |
|
405 |
while (transducer < |
|
406 |
(1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) { |
|
407 |
transducer *= 2; |
|
408 |
exponent--; |
|
409 |
} |
|
410 |
exponent++; |
|
411 |
assert( exponent >= |
|
412 |
DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) && |
|
413 |
exponent < DoubleConsts.MIN_EXPONENT); |
|
414 |
return exponent; |
|
415 |
} |
|
416 |
||
417 |
default: |
|
418 |
assert( exponent >= DoubleConsts.MIN_EXPONENT && |
|
419 |
exponent <= DoubleConsts.MAX_EXPONENT); |
|
420 |
return exponent; |
|
421 |
} |
|
422 |
} |
|
423 |
||
424 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
425 |
* Returns unbiased exponent of a {@code float}; for |
2 | 426 |
* subnormal values, the number is treated as if it were |
427 |
* normalized. That is for all finite, non-zero, positive numbers |
|
428 |
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is |
|
429 |
* always in the range [1, 2). |
|
430 |
* <p> |
|
431 |
* Special cases: |
|
432 |
* <ul> |
|
433 |
* <li> If the argument is NaN, then the result is 2<sup>30</sup>. |
|
434 |
* <li> If the argument is infinite, then the result is 2<sup>28</sup>. |
|
435 |
* <li> If the argument is zero, then the result is -(2<sup>28</sup>). |
|
436 |
* </ul> |
|
437 |
* |
|
438 |
* @param f floating-point number whose exponent is to be extracted |
|
439 |
* @return unbiased exponent of the argument. |
|
440 |
* @author Joseph D. Darcy |
|
441 |
*/ |
|
442 |
public static int ilogb(float f) { |
|
443 |
int exponent = getExponent(f); |
|
444 |
||
445 |
switch (exponent) { |
|
446 |
case FloatConsts.MAX_EXPONENT+1: // NaN or infinity |
|
447 |
if( isNaN(f) ) |
|
448 |
return (1<<30); // 2^30 |
|
449 |
else // infinite value |
|
450 |
return (1<<28); // 2^28 |
|
451 |
||
452 |
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal |
|
453 |
if(f == 0.0f) { |
|
454 |
return -(1<<28); // -(2^28) |
|
455 |
} |
|
456 |
else { |
|
457 |
int transducer = Float.floatToRawIntBits(f); |
|
458 |
||
459 |
/* |
|
460 |
* To avoid causing slow arithmetic on subnormals, |
|
461 |
* the scaling to determine when f's significand |
|
462 |
* is normalized is done in integer arithmetic. |
|
463 |
* (there must be at least one "1" bit in the |
|
464 |
* significand since zero has been screened out. |
|
465 |
*/ |
|
466 |
||
467 |
// isolate significand bits |
|
468 |
transducer &= FloatConsts.SIGNIF_BIT_MASK; |
|
469 |
assert(transducer != 0); |
|
470 |
||
471 |
// This loop is simple and functional. We might be |
|
472 |
// able to do something more clever that was faster; |
|
473 |
// e.g. number of leading zero detection on |
|
474 |
// (transducer << (# exponent and sign bits). |
|
475 |
while (transducer < |
|
476 |
(1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) { |
|
477 |
transducer *= 2; |
|
478 |
exponent--; |
|
479 |
} |
|
480 |
exponent++; |
|
481 |
assert( exponent >= |
|
482 |
FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) && |
|
483 |
exponent < FloatConsts.MIN_EXPONENT); |
|
484 |
return exponent; |
|
485 |
} |
|
486 |
||
487 |
default: |
|
488 |
assert( exponent >= FloatConsts.MIN_EXPONENT && |
|
489 |
exponent <= FloatConsts.MAX_EXPONENT); |
|
490 |
return exponent; |
|
491 |
} |
|
492 |
} |
|
493 |
||
494 |
||
495 |
/* |
|
496 |
* The scalb operation should be reasonably fast; however, there |
|
497 |
* are tradeoffs in writing a method to minimize the worst case |
|
498 |
* performance and writing a method to minimize the time for |
|
499 |
* expected common inputs. Some processors operate very slowly on |
|
500 |
* subnormal operands, taking hundreds or thousands of cycles for |
|
501 |
* one floating-point add or multiply as opposed to, say, four |
|
502 |
* cycles for normal operands. For processors with very slow |
|
503 |
* subnormal execution, scalb would be fastest if written entirely |
|
504 |
* with integer operations; in other words, scalb would need to |
|
505 |
* include the logic of performing correct rounding of subnormal |
|
506 |
* values. This could be reasonably done in at most a few hundred |
|
507 |
* cycles. However, this approach may penalize normal operations |
|
508 |
* since at least the exponent of the floating-point argument must |
|
509 |
* be examined. |
|
510 |
* |
|
511 |
* The approach taken in this implementation is a compromise. |
|
512 |
* Floating-point multiplication is used to do most of the work; |
|
513 |
* but knowingly multiplying by a subnormal scaling factor is |
|
514 |
* avoided. However, the floating-point argument is not examined |
|
515 |
* to see whether or not it is subnormal since subnormal inputs |
|
516 |
* are assumed to be rare. At most three multiplies are needed to |
|
517 |
* scale from the largest to smallest exponent ranges (scaling |
|
518 |
* down, at most two multiplies are needed if subnormal scaling |
|
519 |
* factors are allowed). However, in this implementation an |
|
520 |
* expensive integer remainder operation is avoided at the cost of |
|
521 |
* requiring five floating-point multiplies in the worst case, |
|
522 |
* which should still be a performance win. |
|
523 |
* |
|
524 |
* If scaling of entire arrays is a concern, it would probably be |
|
525 |
* more efficient to provide a double[] scalb(double[], int) |
|
526 |
* version of scalb to avoid having to recompute the needed |
|
527 |
* scaling factors for each floating-point value. |
|
528 |
*/ |
|
529 |
||
530 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
531 |
* Return {@code d} × |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
532 |
* 2<sup>{@code scale_factor}</sup> rounded as if performed |
2 | 533 |
* by a single correctly rounded floating-point multiply to a |
534 |
* member of the double value set. See <a |
|
535 |
* href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#9208">§4.2.3</a> |
|
536 |
* of the <a href="http://java.sun.com/docs/books/jls/html/">Java |
|
537 |
* Language Specification</a> for a discussion of floating-point |
|
538 |
* value sets. If the exponent of the result is between the |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
539 |
* {@code double}'s minimum exponent and maximum exponent, |
2 | 540 |
* the answer is calculated exactly. If the exponent of the |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
541 |
* result would be larger than {@code doubles}'s maximum |
2 | 542 |
* exponent, an infinity is returned. Note that if the result is |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
543 |
* subnormal, precision may be lost; that is, when {@code scalb(x, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
544 |
* n)} is subnormal, {@code scalb(scalb(x, n), -n)} may |
2 | 545 |
* not equal <i>x</i>. When the result is non-NaN, the result has |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
546 |
* the same sign as {@code d}. |
2 | 547 |
* |
548 |
*<p> |
|
549 |
* Special cases: |
|
550 |
* <ul> |
|
551 |
* <li> If the first argument is NaN, NaN is returned. |
|
552 |
* <li> If the first argument is infinite, then an infinity of the |
|
553 |
* same sign is returned. |
|
554 |
* <li> If the first argument is zero, then a zero of the same |
|
555 |
* sign is returned. |
|
556 |
* </ul> |
|
557 |
* |
|
558 |
* @param d number to be scaled by a power of two. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
559 |
* @param scale_factor power of 2 used to scale {@code d} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
560 |
* @return {@code d * }2<sup>{@code scale_factor}</sup> |
2 | 561 |
* @author Joseph D. Darcy |
562 |
*/ |
|
563 |
public static double scalb(double d, int scale_factor) { |
|
564 |
/* |
|
565 |
* This method does not need to be declared strictfp to |
|
566 |
* compute the same correct result on all platforms. When |
|
567 |
* scaling up, it does not matter what order the |
|
568 |
* multiply-store operations are done; the result will be |
|
569 |
* finite or overflow regardless of the operation ordering. |
|
570 |
* However, to get the correct result when scaling down, a |
|
571 |
* particular ordering must be used. |
|
572 |
* |
|
573 |
* When scaling down, the multiply-store operations are |
|
574 |
* sequenced so that it is not possible for two consecutive |
|
575 |
* multiply-stores to return subnormal results. If one |
|
576 |
* multiply-store result is subnormal, the next multiply will |
|
577 |
* round it away to zero. This is done by first multiplying |
|
578 |
* by 2 ^ (scale_factor % n) and then multiplying several |
|
579 |
* times by by 2^n as needed where n is the exponent of number |
|
580 |
* that is a covenient power of two. In this way, at most one |
|
581 |
* real rounding error occurs. If the double value set is |
|
582 |
* being used exclusively, the rounding will occur on a |
|
583 |
* multiply. If the double-extended-exponent value set is |
|
584 |
* being used, the products will (perhaps) be exact but the |
|
585 |
* stores to d are guaranteed to round to the double value |
|
586 |
* set. |
|
587 |
* |
|
588 |
* It is _not_ a valid implementation to first multiply d by |
|
589 |
* 2^MIN_EXPONENT and then by 2 ^ (scale_factor % |
|
590 |
* MIN_EXPONENT) since even in a strictfp program double |
|
591 |
* rounding on underflow could occur; e.g. if the scale_factor |
|
592 |
* argument was (MIN_EXPONENT - n) and the exponent of d was a |
|
593 |
* little less than -(MIN_EXPONENT - n), meaning the final |
|
594 |
* result would be subnormal. |
|
595 |
* |
|
596 |
* Since exact reproducibility of this method can be achieved |
|
597 |
* without any undue performance burden, there is no |
|
598 |
* compelling reason to allow double rounding on underflow in |
|
599 |
* scalb. |
|
600 |
*/ |
|
601 |
||
602 |
// magnitude of a power of two so large that scaling a finite |
|
603 |
// nonzero value by it would be guaranteed to over or |
|
604 |
// underflow; due to rounding, scaling down takes takes an |
|
605 |
// additional power of two which is reflected here |
|
606 |
final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT + |
|
607 |
DoubleConsts.SIGNIFICAND_WIDTH + 1; |
|
608 |
int exp_adjust = 0; |
|
609 |
int scale_increment = 0; |
|
610 |
double exp_delta = Double.NaN; |
|
611 |
||
612 |
// Make sure scaling factor is in a reasonable range |
|
613 |
||
614 |
if(scale_factor < 0) { |
|
615 |
scale_factor = Math.max(scale_factor, -MAX_SCALE); |
|
616 |
scale_increment = -512; |
|
617 |
exp_delta = twoToTheDoubleScaleDown; |
|
618 |
} |
|
619 |
else { |
|
620 |
scale_factor = Math.min(scale_factor, MAX_SCALE); |
|
621 |
scale_increment = 512; |
|
622 |
exp_delta = twoToTheDoubleScaleUp; |
|
623 |
} |
|
624 |
||
625 |
// Calculate (scale_factor % +/-512), 512 = 2^9, using |
|
626 |
// technique from "Hacker's Delight" section 10-2. |
|
627 |
int t = (scale_factor >> 9-1) >>> 32 - 9; |
|
628 |
exp_adjust = ((scale_factor + t) & (512 -1)) - t; |
|
629 |
||
630 |
d *= powerOfTwoD(exp_adjust); |
|
631 |
scale_factor -= exp_adjust; |
|
632 |
||
633 |
while(scale_factor != 0) { |
|
634 |
d *= exp_delta; |
|
635 |
scale_factor -= scale_increment; |
|
636 |
} |
|
637 |
return d; |
|
638 |
} |
|
639 |
||
640 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
641 |
* Return {@code f} × |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
642 |
* 2<sup>{@code scale_factor}</sup> rounded as if performed |
2 | 643 |
* by a single correctly rounded floating-point multiply to a |
644 |
* member of the float value set. See <a |
|
645 |
* href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#9208">§4.2.3</a> |
|
646 |
* of the <a href="http://java.sun.com/docs/books/jls/html/">Java |
|
647 |
* Language Specification</a> for a discussion of floating-point |
|
648 |
* value set. If the exponent of the result is between the |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
649 |
* {@code float}'s minimum exponent and maximum exponent, the |
2 | 650 |
* answer is calculated exactly. If the exponent of the result |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
651 |
* would be larger than {@code float}'s maximum exponent, an |
2 | 652 |
* infinity is returned. Note that if the result is subnormal, |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
653 |
* precision may be lost; that is, when {@code scalb(x, n)} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
654 |
* is subnormal, {@code scalb(scalb(x, n), -n)} may not equal |
2 | 655 |
* <i>x</i>. When the result is non-NaN, the result has the same |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
656 |
* sign as {@code f}. |
2 | 657 |
* |
658 |
*<p> |
|
659 |
* Special cases: |
|
660 |
* <ul> |
|
661 |
* <li> If the first argument is NaN, NaN is returned. |
|
662 |
* <li> If the first argument is infinite, then an infinity of the |
|
663 |
* same sign is returned. |
|
664 |
* <li> If the first argument is zero, then a zero of the same |
|
665 |
* sign is returned. |
|
666 |
* </ul> |
|
667 |
* |
|
668 |
* @param f number to be scaled by a power of two. |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
669 |
* @param scale_factor power of 2 used to scale {@code f} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
670 |
* @return {@code f * }2<sup>{@code scale_factor}</sup> |
2 | 671 |
* @author Joseph D. Darcy |
672 |
*/ |
|
673 |
public static float scalb(float f, int scale_factor) { |
|
674 |
// magnitude of a power of two so large that scaling a finite |
|
675 |
// nonzero value by it would be guaranteed to over or |
|
676 |
// underflow; due to rounding, scaling down takes takes an |
|
677 |
// additional power of two which is reflected here |
|
678 |
final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT + |
|
679 |
FloatConsts.SIGNIFICAND_WIDTH + 1; |
|
680 |
||
681 |
// Make sure scaling factor is in a reasonable range |
|
682 |
scale_factor = Math.max(Math.min(scale_factor, MAX_SCALE), -MAX_SCALE); |
|
683 |
||
684 |
/* |
|
685 |
* Since + MAX_SCALE for float fits well within the double |
|
686 |
* exponent range and + float -> double conversion is exact |
|
687 |
* the multiplication below will be exact. Therefore, the |
|
688 |
* rounding that occurs when the double product is cast to |
|
689 |
* float will be the correctly rounded float result. Since |
|
690 |
* all operations other than the final multiply will be exact, |
|
691 |
* it is not necessary to declare this method strictfp. |
|
692 |
*/ |
|
693 |
return (float)((double)f*powerOfTwoD(scale_factor)); |
|
694 |
} |
|
695 |
||
696 |
/** |
|
697 |
* Returns the floating-point number adjacent to the first |
|
698 |
* argument in the direction of the second argument. If both |
|
699 |
* arguments compare as equal the second argument is returned. |
|
700 |
* |
|
701 |
* <p> |
|
702 |
* Special cases: |
|
703 |
* <ul> |
|
704 |
* <li> If either argument is a NaN, then NaN is returned. |
|
705 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
706 |
* <li> If both arguments are signed zeros, {@code direction} |
2 | 707 |
* is returned unchanged (as implied by the requirement of |
708 |
* returning the second argument if the arguments compare as |
|
709 |
* equal). |
|
710 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
711 |
* <li> If {@code start} is |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
712 |
* ±{@code Double.MIN_VALUE} and {@code direction} |
2 | 713 |
* has a value such that the result should have a smaller |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
714 |
* magnitude, then a zero with the same sign as {@code start} |
2 | 715 |
* is returned. |
716 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
717 |
* <li> If {@code start} is infinite and |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
718 |
* {@code direction} has a value such that the result should |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
719 |
* have a smaller magnitude, {@code Double.MAX_VALUE} with the |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
720 |
* same sign as {@code start} is returned. |
2 | 721 |
* |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
722 |
* <li> If {@code start} is equal to ± |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
723 |
* {@code Double.MAX_VALUE} and {@code direction} has a |
2 | 724 |
* value such that the result should have a larger magnitude, an |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
725 |
* infinity with same sign as {@code start} is returned. |
2 | 726 |
* </ul> |
727 |
* |
|
728 |
* @param start starting floating-point value |
|
729 |
* @param direction value indicating which of |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
730 |
* {@code start}'s neighbors or {@code start} should |
2 | 731 |
* be returned |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
732 |
* @return The floating-point number adjacent to {@code start} in the |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
733 |
* direction of {@code direction}. |
2 | 734 |
* @author Joseph D. Darcy |
735 |
*/ |
|
736 |
public static double nextAfter(double start, double direction) { |
|
737 |
/* |
|
738 |
* The cases: |
|
739 |
* |
|
740 |
* nextAfter(+infinity, 0) == MAX_VALUE |
|
741 |
* nextAfter(+infinity, +infinity) == +infinity |
|
742 |
* nextAfter(-infinity, 0) == -MAX_VALUE |
|
743 |
* nextAfter(-infinity, -infinity) == -infinity |
|
744 |
* |
|
745 |
* are naturally handled without any additional testing |
|
746 |
*/ |
|
747 |
||
748 |
// First check for NaN values |
|
749 |
if (isNaN(start) || isNaN(direction)) { |
|
750 |
// return a NaN derived from the input NaN(s) |
|
751 |
return start + direction; |
|
752 |
} else if (start == direction) { |
|
753 |
return direction; |
|
754 |
} else { // start > direction or start < direction |
|
755 |
// Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0) |
|
756 |
// then bitwise convert start to integer. |
|
757 |
long transducer = Double.doubleToRawLongBits(start + 0.0d); |
|
758 |
||
759 |
/* |
|
760 |
* IEEE 754 floating-point numbers are lexicographically |
|
761 |
* ordered if treated as signed- magnitude integers . |
|
762 |
* Since Java's integers are two's complement, |
|
763 |
* incrementing" the two's complement representation of a |
|
764 |
* logically negative floating-point value *decrements* |
|
765 |
* the signed-magnitude representation. Therefore, when |
|
766 |
* the integer representation of a floating-point values |
|
767 |
* is less than zero, the adjustment to the representation |
|
768 |
* is in the opposite direction than would be expected at |
|
769 |
* first . |
|
770 |
*/ |
|
771 |
if (direction > start) { // Calculate next greater value |
|
772 |
transducer = transducer + (transducer >= 0L ? 1L:-1L); |
|
773 |
} else { // Calculate next lesser value |
|
774 |
assert direction < start; |
|
775 |
if (transducer > 0L) |
|
776 |
--transducer; |
|
777 |
else |
|
778 |
if (transducer < 0L ) |
|
779 |
++transducer; |
|
780 |
/* |
|
781 |
* transducer==0, the result is -MIN_VALUE |
|
782 |
* |
|
783 |
* The transition from zero (implicitly |
|
784 |
* positive) to the smallest negative |
|
785 |
* signed magnitude value must be done |
|
786 |
* explicitly. |
|
787 |
*/ |
|
788 |
else |
|
789 |
transducer = DoubleConsts.SIGN_BIT_MASK | 1L; |
|
790 |
} |
|
791 |
||
792 |
return Double.longBitsToDouble(transducer); |
|
793 |
} |
|
794 |
} |
|
795 |
||
796 |
/** |
|
797 |
* Returns the floating-point number adjacent to the first |
|
798 |
* argument in the direction of the second argument. If both |
|
799 |
* arguments compare as equal, the second argument is returned. |
|
800 |
* |
|
801 |
* <p> |
|
802 |
* Special cases: |
|
803 |
* <ul> |
|
804 |
* <li> If either argument is a NaN, then NaN is returned. |
|
805 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
806 |
* <li> If both arguments are signed zeros, a {@code float} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
807 |
* zero with the same sign as {@code direction} is returned |
2 | 808 |
* (as implied by the requirement of returning the second argument |
809 |
* if the arguments compare as equal). |
|
810 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
811 |
* <li> If {@code start} is |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
812 |
* ±{@code Float.MIN_VALUE} and {@code direction} |
2 | 813 |
* has a value such that the result should have a smaller |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
814 |
* magnitude, then a zero with the same sign as {@code start} |
2 | 815 |
* is returned. |
816 |
* |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
817 |
* <li> If {@code start} is infinite and |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
818 |
* {@code direction} has a value such that the result should |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
819 |
* have a smaller magnitude, {@code Float.MAX_VALUE} with the |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
820 |
* same sign as {@code start} is returned. |
2 | 821 |
* |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
822 |
* <li> If {@code start} is equal to ± |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
823 |
* {@code Float.MAX_VALUE} and {@code direction} has a |
2 | 824 |
* value such that the result should have a larger magnitude, an |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
825 |
* infinity with same sign as {@code start} is returned. |
2 | 826 |
* </ul> |
827 |
* |
|
828 |
* @param start starting floating-point value |
|
829 |
* @param direction value indicating which of |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
830 |
* {@code start}'s neighbors or {@code start} should |
2 | 831 |
* be returned |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
832 |
* @return The floating-point number adjacent to {@code start} in the |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
833 |
* direction of {@code direction}. |
2 | 834 |
* @author Joseph D. Darcy |
835 |
*/ |
|
836 |
public static float nextAfter(float start, double direction) { |
|
837 |
/* |
|
838 |
* The cases: |
|
839 |
* |
|
840 |
* nextAfter(+infinity, 0) == MAX_VALUE |
|
841 |
* nextAfter(+infinity, +infinity) == +infinity |
|
842 |
* nextAfter(-infinity, 0) == -MAX_VALUE |
|
843 |
* nextAfter(-infinity, -infinity) == -infinity |
|
844 |
* |
|
845 |
* are naturally handled without any additional testing |
|
846 |
*/ |
|
847 |
||
848 |
// First check for NaN values |
|
849 |
if (isNaN(start) || isNaN(direction)) { |
|
850 |
// return a NaN derived from the input NaN(s) |
|
851 |
return start + (float)direction; |
|
852 |
} else if (start == direction) { |
|
853 |
return (float)direction; |
|
854 |
} else { // start > direction or start < direction |
|
855 |
// Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0) |
|
856 |
// then bitwise convert start to integer. |
|
857 |
int transducer = Float.floatToRawIntBits(start + 0.0f); |
|
858 |
||
859 |
/* |
|
860 |
* IEEE 754 floating-point numbers are lexicographically |
|
861 |
* ordered if treated as signed- magnitude integers . |
|
862 |
* Since Java's integers are two's complement, |
|
863 |
* incrementing" the two's complement representation of a |
|
864 |
* logically negative floating-point value *decrements* |
|
865 |
* the signed-magnitude representation. Therefore, when |
|
866 |
* the integer representation of a floating-point values |
|
867 |
* is less than zero, the adjustment to the representation |
|
868 |
* is in the opposite direction than would be expected at |
|
869 |
* first. |
|
870 |
*/ |
|
871 |
if (direction > start) {// Calculate next greater value |
|
872 |
transducer = transducer + (transducer >= 0 ? 1:-1); |
|
873 |
} else { // Calculate next lesser value |
|
874 |
assert direction < start; |
|
875 |
if (transducer > 0) |
|
876 |
--transducer; |
|
877 |
else |
|
878 |
if (transducer < 0 ) |
|
879 |
++transducer; |
|
880 |
/* |
|
881 |
* transducer==0, the result is -MIN_VALUE |
|
882 |
* |
|
883 |
* The transition from zero (implicitly |
|
884 |
* positive) to the smallest negative |
|
885 |
* signed magnitude value must be done |
|
886 |
* explicitly. |
|
887 |
*/ |
|
888 |
else |
|
889 |
transducer = FloatConsts.SIGN_BIT_MASK | 1; |
|
890 |
} |
|
891 |
||
892 |
return Float.intBitsToFloat(transducer); |
|
893 |
} |
|
894 |
} |
|
895 |
||
896 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
897 |
* Returns the floating-point value adjacent to {@code d} in |
2 | 898 |
* the direction of positive infinity. This method is |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
899 |
* semantically equivalent to {@code nextAfter(d, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
900 |
* Double.POSITIVE_INFINITY)}; however, a {@code nextUp} |
2 | 901 |
* implementation may run faster than its equivalent |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
902 |
* {@code nextAfter} call. |
2 | 903 |
* |
904 |
* <p>Special Cases: |
|
905 |
* <ul> |
|
906 |
* <li> If the argument is NaN, the result is NaN. |
|
907 |
* |
|
908 |
* <li> If the argument is positive infinity, the result is |
|
909 |
* positive infinity. |
|
910 |
* |
|
911 |
* <li> If the argument is zero, the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
912 |
* {@code Double.MIN_VALUE} |
2 | 913 |
* |
914 |
* </ul> |
|
915 |
* |
|
916 |
* @param d starting floating-point value |
|
917 |
* @return The adjacent floating-point value closer to positive |
|
918 |
* infinity. |
|
919 |
* @author Joseph D. Darcy |
|
920 |
*/ |
|
921 |
public static double nextUp(double d) { |
|
922 |
if( isNaN(d) || d == Double.POSITIVE_INFINITY) |
|
923 |
return d; |
|
924 |
else { |
|
925 |
d += 0.0d; |
|
926 |
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) + |
|
927 |
((d >= 0.0d)?+1L:-1L)); |
|
928 |
} |
|
929 |
} |
|
930 |
||
931 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
932 |
* Returns the floating-point value adjacent to {@code f} in |
2 | 933 |
* the direction of positive infinity. This method is |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
934 |
* semantically equivalent to {@code nextAfter(f, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
935 |
* Double.POSITIVE_INFINITY)}; however, a {@code nextUp} |
2 | 936 |
* implementation may run faster than its equivalent |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
937 |
* {@code nextAfter} call. |
2 | 938 |
* |
939 |
* <p>Special Cases: |
|
940 |
* <ul> |
|
941 |
* <li> If the argument is NaN, the result is NaN. |
|
942 |
* |
|
943 |
* <li> If the argument is positive infinity, the result is |
|
944 |
* positive infinity. |
|
945 |
* |
|
946 |
* <li> If the argument is zero, the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
947 |
* {@code Float.MIN_VALUE} |
2 | 948 |
* |
949 |
* </ul> |
|
950 |
* |
|
951 |
* @param f starting floating-point value |
|
952 |
* @return The adjacent floating-point value closer to positive |
|
953 |
* infinity. |
|
954 |
* @author Joseph D. Darcy |
|
955 |
*/ |
|
956 |
public static float nextUp(float f) { |
|
957 |
if( isNaN(f) || f == FloatConsts.POSITIVE_INFINITY) |
|
958 |
return f; |
|
959 |
else { |
|
960 |
f += 0.0f; |
|
961 |
return Float.intBitsToFloat(Float.floatToRawIntBits(f) + |
|
962 |
((f >= 0.0f)?+1:-1)); |
|
963 |
} |
|
964 |
} |
|
965 |
||
966 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
967 |
* Returns the floating-point value adjacent to {@code d} in |
2 | 968 |
* the direction of negative infinity. This method is |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
969 |
* semantically equivalent to {@code nextAfter(d, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
970 |
* Double.NEGATIVE_INFINITY)}; however, a |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
971 |
* {@code nextDown} implementation may run faster than its |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
972 |
* equivalent {@code nextAfter} call. |
2 | 973 |
* |
974 |
* <p>Special Cases: |
|
975 |
* <ul> |
|
976 |
* <li> If the argument is NaN, the result is NaN. |
|
977 |
* |
|
978 |
* <li> If the argument is negative infinity, the result is |
|
979 |
* negative infinity. |
|
980 |
* |
|
981 |
* <li> If the argument is zero, the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
982 |
* {@code -Double.MIN_VALUE} |
2 | 983 |
* |
984 |
* </ul> |
|
985 |
* |
|
986 |
* @param d starting floating-point value |
|
987 |
* @return The adjacent floating-point value closer to negative |
|
988 |
* infinity. |
|
989 |
* @author Joseph D. Darcy |
|
990 |
*/ |
|
991 |
public static double nextDown(double d) { |
|
992 |
if( isNaN(d) || d == Double.NEGATIVE_INFINITY) |
|
993 |
return d; |
|
994 |
else { |
|
995 |
if (d == 0.0) |
|
996 |
return -Double.MIN_VALUE; |
|
997 |
else |
|
998 |
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) + |
|
999 |
((d > 0.0d)?-1L:+1L)); |
|
1000 |
} |
|
1001 |
} |
|
1002 |
||
1003 |
/** |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1004 |
* Returns the floating-point value adjacent to {@code f} in |
2 | 1005 |
* the direction of negative infinity. This method is |
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1006 |
* semantically equivalent to {@code nextAfter(f, |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1007 |
* Float.NEGATIVE_INFINITY)}; however, a |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1008 |
* {@code nextDown} implementation may run faster than its |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1009 |
* equivalent {@code nextAfter} call. |
2 | 1010 |
* |
1011 |
* <p>Special Cases: |
|
1012 |
* <ul> |
|
1013 |
* <li> If the argument is NaN, the result is NaN. |
|
1014 |
* |
|
1015 |
* <li> If the argument is negative infinity, the result is |
|
1016 |
* negative infinity. |
|
1017 |
* |
|
1018 |
* <li> If the argument is zero, the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1019 |
* {@code -Float.MIN_VALUE} |
2 | 1020 |
* |
1021 |
* </ul> |
|
1022 |
* |
|
1023 |
* @param f starting floating-point value |
|
1024 |
* @return The adjacent floating-point value closer to negative |
|
1025 |
* infinity. |
|
1026 |
* @author Joseph D. Darcy |
|
1027 |
*/ |
|
1028 |
public static double nextDown(float f) { |
|
1029 |
if( isNaN(f) || f == Float.NEGATIVE_INFINITY) |
|
1030 |
return f; |
|
1031 |
else { |
|
1032 |
if (f == 0.0f) |
|
1033 |
return -Float.MIN_VALUE; |
|
1034 |
else |
|
1035 |
return Float.intBitsToFloat(Float.floatToRawIntBits(f) + |
|
1036 |
((f > 0.0f)?-1:+1)); |
|
1037 |
} |
|
1038 |
} |
|
1039 |
||
1040 |
/** |
|
1041 |
* Returns the first floating-point argument with the sign of the |
|
1042 |
* second floating-point argument. For this method, a NaN |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1043 |
* {@code sign} argument is always treated as if it were |
2 | 1044 |
* positive. |
1045 |
* |
|
1046 |
* @param magnitude the parameter providing the magnitude of the result |
|
1047 |
* @param sign the parameter providing the sign of the result |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1048 |
* @return a value with the magnitude of {@code magnitude} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1049 |
* and the sign of {@code sign}. |
2 | 1050 |
* @author Joseph D. Darcy |
1051 |
* @since 1.5 |
|
1052 |
*/ |
|
1053 |
public static double copySign(double magnitude, double sign) { |
|
1054 |
return rawCopySign(magnitude, (isNaN(sign)?1.0d:sign)); |
|
1055 |
} |
|
1056 |
||
1057 |
/** |
|
1058 |
* Returns the first floating-point argument with the sign of the |
|
1059 |
* second floating-point argument. For this method, a NaN |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1060 |
* {@code sign} argument is always treated as if it were |
2 | 1061 |
* positive. |
1062 |
* |
|
1063 |
* @param magnitude the parameter providing the magnitude of the result |
|
1064 |
* @param sign the parameter providing the sign of the result |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1065 |
* @return a value with the magnitude of {@code magnitude} |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1066 |
* and the sign of {@code sign}. |
2 | 1067 |
* @author Joseph D. Darcy |
1068 |
*/ |
|
1069 |
public static float copySign(float magnitude, float sign) { |
|
1070 |
return rawCopySign(magnitude, (isNaN(sign)?1.0f:sign)); |
|
1071 |
} |
|
1072 |
||
1073 |
/** |
|
1074 |
* Returns the size of an ulp of the argument. An ulp of a |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1075 |
* {@code double} value is the positive distance between this |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1076 |
* floating-point value and the {@code double} value next |
2 | 1077 |
* larger in magnitude. Note that for non-NaN <i>x</i>, |
1078 |
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>. |
|
1079 |
* |
|
1080 |
* <p>Special Cases: |
|
1081 |
* <ul> |
|
1082 |
* <li> If the argument is NaN, then the result is NaN. |
|
1083 |
* <li> If the argument is positive or negative infinity, then the |
|
1084 |
* result is positive infinity. |
|
1085 |
* <li> If the argument is positive or negative zero, then the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1086 |
* {@code Double.MIN_VALUE}. |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1087 |
* <li> If the argument is ±{@code Double.MAX_VALUE}, then |
2 | 1088 |
* the result is equal to 2<sup>971</sup>. |
1089 |
* </ul> |
|
1090 |
* |
|
1091 |
* @param d the floating-point value whose ulp is to be returned |
|
1092 |
* @return the size of an ulp of the argument |
|
1093 |
* @author Joseph D. Darcy |
|
1094 |
* @since 1.5 |
|
1095 |
*/ |
|
1096 |
public static double ulp(double d) { |
|
1097 |
int exp = getExponent(d); |
|
1098 |
||
1099 |
switch(exp) { |
|
1100 |
case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity |
|
1101 |
return Math.abs(d); |
|
1102 |
||
1103 |
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal |
|
1104 |
return Double.MIN_VALUE; |
|
1105 |
||
1106 |
default: |
|
1107 |
assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT; |
|
1108 |
||
1109 |
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x)) |
|
1110 |
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1); |
|
1111 |
if (exp >= DoubleConsts.MIN_EXPONENT) { |
|
1112 |
return powerOfTwoD(exp); |
|
1113 |
} |
|
1114 |
else { |
|
1115 |
// return a subnormal result; left shift integer |
|
1116 |
// representation of Double.MIN_VALUE appropriate |
|
1117 |
// number of positions |
|
1118 |
return Double.longBitsToDouble(1L << |
|
1119 |
(exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) )); |
|
1120 |
} |
|
1121 |
} |
|
1122 |
} |
|
1123 |
||
1124 |
/** |
|
1125 |
* Returns the size of an ulp of the argument. An ulp of a |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1126 |
* {@code float} value is the positive distance between this |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1127 |
* floating-point value and the {@code float} value next |
2 | 1128 |
* larger in magnitude. Note that for non-NaN <i>x</i>, |
1129 |
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>. |
|
1130 |
* |
|
1131 |
* <p>Special Cases: |
|
1132 |
* <ul> |
|
1133 |
* <li> If the argument is NaN, then the result is NaN. |
|
1134 |
* <li> If the argument is positive or negative infinity, then the |
|
1135 |
* result is positive infinity. |
|
1136 |
* <li> If the argument is positive or negative zero, then the result is |
|
7517
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1137 |
* {@code Float.MIN_VALUE}. |
7303bc0e78d6
7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0
darcy
parents:
5506
diff
changeset
|
1138 |
* <li> If the argument is ±{@code Float.MAX_VALUE}, then |
2 | 1139 |
* the result is equal to 2<sup>104</sup>. |
1140 |
* </ul> |
|
1141 |
* |
|
1142 |
* @param f the floating-point value whose ulp is to be returned |
|
1143 |
* @return the size of an ulp of the argument |
|
1144 |
* @author Joseph D. Darcy |
|
1145 |
* @since 1.5 |
|
1146 |
*/ |
|
1147 |
public static float ulp(float f) { |
|
1148 |
int exp = getExponent(f); |
|
1149 |
||
1150 |
switch(exp) { |
|
1151 |
case FloatConsts.MAX_EXPONENT+1: // NaN or infinity |
|
1152 |
return Math.abs(f); |
|
1153 |
||
1154 |
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal |
|
1155 |
return FloatConsts.MIN_VALUE; |
|
1156 |
||
1157 |
default: |
|
1158 |
assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT; |
|
1159 |
||
1160 |
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x)) |
|
1161 |
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1); |
|
1162 |
if (exp >= FloatConsts.MIN_EXPONENT) { |
|
1163 |
return powerOfTwoF(exp); |
|
1164 |
} |
|
1165 |
else { |
|
1166 |
// return a subnormal result; left shift integer |
|
1167 |
// representation of FloatConsts.MIN_VALUE appropriate |
|
1168 |
// number of positions |
|
1169 |
return Float.intBitsToFloat(1 << |
|
1170 |
(exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) )); |
|
1171 |
} |
|
1172 |
} |
|
1173 |
} |
|
1174 |
||
1175 |
/** |
|
1176 |
* Returns the signum function of the argument; zero if the argument |
|
1177 |
* is zero, 1.0 if the argument is greater than zero, -1.0 if the |
|
1178 |
* argument is less than zero. |
|
1179 |
* |
|
1180 |
* <p>Special Cases: |
|
1181 |
* <ul> |
|
1182 |
* <li> If the argument is NaN, then the result is NaN. |
|
1183 |
* <li> If the argument is positive zero or negative zero, then the |
|
1184 |
* result is the same as the argument. |
|
1185 |
* </ul> |
|
1186 |
* |
|
1187 |
* @param d the floating-point value whose signum is to be returned |
|
1188 |
* @return the signum function of the argument |
|
1189 |
* @author Joseph D. Darcy |
|
1190 |
* @since 1.5 |
|
1191 |
*/ |
|
1192 |
public static double signum(double d) { |
|
1193 |
return (d == 0.0 || isNaN(d))?d:copySign(1.0, d); |
|
1194 |
} |
|
1195 |
||
1196 |
/** |
|
1197 |
* Returns the signum function of the argument; zero if the argument |
|
1198 |
* is zero, 1.0f if the argument is greater than zero, -1.0f if the |
|
1199 |
* argument is less than zero. |
|
1200 |
* |
|
1201 |
* <p>Special Cases: |
|
1202 |
* <ul> |
|
1203 |
* <li> If the argument is NaN, then the result is NaN. |
|
1204 |
* <li> If the argument is positive zero or negative zero, then the |
|
1205 |
* result is the same as the argument. |
|
1206 |
* </ul> |
|
1207 |
* |
|
1208 |
* @param f the floating-point value whose signum is to be returned |
|
1209 |
* @return the signum function of the argument |
|
1210 |
* @author Joseph D. Darcy |
|
1211 |
* @since 1.5 |
|
1212 |
*/ |
|
1213 |
public static float signum(float f) { |
|
1214 |
return (f == 0.0f || isNaN(f))?f:copySign(1.0f, f); |
|
1215 |
} |
|
1216 |
||
1217 |
} |