提交 fe7ceb20 编写于 作者: D darcy

7002594: Math.max and Math.min should use floatToRawIntBits() to check for -0.0

Reviewed-by: mduigou, lancea, alanb
上级 89389743
/* /*
* Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -973,7 +973,8 @@ public final class Double extends Number implements Comparable<Double> { ...@@ -973,7 +973,8 @@ public final class Double extends Number implements Comparable<Double> {
if (d1 > d2) if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger return 1; // Neither val is NaN, thisVal is larger
long thisBits = Double.doubleToLongBits(d1); // Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2); long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal return (thisBits == anotherBits ? 0 : // Values are equal
......
/* /*
* Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -872,12 +872,13 @@ public final class Float extends Number implements Comparable<Float> { ...@@ -872,12 +872,13 @@ public final class Float extends Number implements Comparable<Float> {
* @since 1.4 * @since 1.4
*/ */
public static int compare(float f1, float f2) { public static int compare(float f1, float f2) {
if (f1 < f2) if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2) if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger return 1; // Neither val is NaN, thisVal is larger
int thisBits = Float.floatToIntBits(f1); // Cannot use floatToRawIntBits because of possibility of NaNs.
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2); int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal return (thisBits == anotherBits ? 0 : // Values are equal
......
/* /*
* Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -801,8 +801,9 @@ public final class StrictMath { ...@@ -801,8 +801,9 @@ public final class StrictMath {
return (a >= b) ? a : b; return (a >= b) ? a : b;
} }
private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f); // Use raw bit-wise conversions on guaranteed non-NaN arguments.
private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d); private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
/** /**
* Returns the greater of two {@code float} values. That is, * Returns the greater of two {@code float} values. That is,
...@@ -819,9 +820,12 @@ public final class StrictMath { ...@@ -819,9 +820,12 @@ public final class StrictMath {
* @return the larger of {@code a} and {@code b}. * @return the larger of {@code a} and {@code b}.
*/ */
public static float max(float a, float b) { public static float max(float a, float b) {
if (a != a) return a; // a is NaN if (a != a)
if ((a == 0.0f) && (b == 0.0f) return a; // a is NaN
&& (Float.floatToIntBits(a) == negativeZeroFloatBits)) { if ((a == 0.0f) &&
(b == 0.0f) &&
(Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b; return b;
} }
return (a >= b) ? a : b; return (a >= b) ? a : b;
...@@ -842,9 +846,12 @@ public final class StrictMath { ...@@ -842,9 +846,12 @@ public final class StrictMath {
* @return the larger of {@code a} and {@code b}. * @return the larger of {@code a} and {@code b}.
*/ */
public static double max(double a, double b) { public static double max(double a, double b) {
if (a != a) return a; // a is NaN if (a != a)
if ((a == 0.0d) && (b == 0.0d) return a; // a is NaN
&& (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) { if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b; return b;
} }
return (a >= b) ? a : b; return (a >= b) ? a : b;
...@@ -893,9 +900,12 @@ public final class StrictMath { ...@@ -893,9 +900,12 @@ public final class StrictMath {
* @return the smaller of {@code a} and {@code b.} * @return the smaller of {@code a} and {@code b.}
*/ */
public static float min(float a, float b) { public static float min(float a, float b) {
if (a != a) return a; // a is NaN if (a != a)
if ((a == 0.0f) && (b == 0.0f) return a; // a is NaN
&& (Float.floatToIntBits(b) == negativeZeroFloatBits)) { if ((a == 0.0f) &&
(b == 0.0f) &&
(Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b; return b;
} }
return (a <= b) ? a : b; return (a <= b) ? a : b;
...@@ -916,9 +926,12 @@ public final class StrictMath { ...@@ -916,9 +926,12 @@ public final class StrictMath {
* @return the smaller of {@code a} and {@code b}. * @return the smaller of {@code a} and {@code b}.
*/ */
public static double min(double a, double b) { public static double min(double a, double b) {
if (a != a) return a; // a is NaN if (a != a)
if ((a == 0.0d) && (b == 0.0d) return a; // a is NaN
&& (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) { if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b; return b;
} }
return (a <= b) ? a : b; return (a <= b) ? a : b;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册