6903754: (bf) Improve floating-point buffer comparison
Describe the exact behavior of {Double,Float}Buffer.{equals,compareTo}; fix non-anti-symmetric behavior of compareTo
Reviewed-by: alanb
diff --git a/jdk/test/java/nio/Buffer/Basic-X.java.template b/jdk/test/java/nio/Buffer/Basic-X.java.template
index 6612771..93cbe8e 100644
--- a/jdk/test/java/nio/Buffer/Basic-X.java.template
+++ b/jdk/test/java/nio/Buffer/Basic-X.java.template
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final $type$[] VALUES = {
+ $Fulltype$.MIN_VALUE,
+ ($type$) -1,
+ ($type$) 0,
+ ($type$) 1,
+ $Fulltype$.MAX_VALUE,
+#if[float]
+ $Fulltype$.NEGATIVE_INFINITY,
+ $Fulltype$.POSITIVE_INFINITY,
+ $Fulltype$.NaN,
+ ($type$) -0.0,
+#end[float]
+#if[double]
+ $Fulltype$.NEGATIVE_INFINITY,
+ $Fulltype$.POSITIVE_INFINITY,
+ $Fulltype$.NaN,
+ ($type$) -0.0,
+#end[double]
+ };
+
private static void relGet($Type$Buffer b) {
int n = b.capacity();
$type$ v;
@@ -309,6 +329,12 @@
#end[byte]
+ private static void fail(String problem,
+ $Type$Buffer xb, $Type$Buffer yb,
+ $type$ x, $type$ y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for ($type$ x : VALUES) {
+ $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for ($type$ y : VALUES) {
+ $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) {
+#if[float]
+ if (x == 0.0 && y == 0.0) continue;
+#end[float]
+#if[double]
+ if (x == 0.0 && y == 0.0) continue;
+#end[double]
+ fail("Incorrect results for $Type$Buffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for $Type$Buffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicByte.java b/jdk/test/java/nio/Buffer/BasicByte.java
index 7e259a1..78b2099 100644
--- a/jdk/test/java/nio/Buffer/BasicByte.java
+++ b/jdk/test/java/nio/Buffer/BasicByte.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final byte[] VALUES = {
+ Byte.MIN_VALUE,
+ (byte) -1,
+ (byte) 0,
+ (byte) 1,
+ Byte.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(ByteBuffer b) {
int n = b.capacity();
byte v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ ByteBuffer xb, ByteBuffer yb,
+ byte x, byte y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (byte x : VALUES) {
+ ByteBuffer xb = ByteBuffer.wrap(new byte[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (byte y : VALUES) {
+ ByteBuffer yb = ByteBuffer.wrap(new byte[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Byte.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for ByteBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for ByteBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicChar.java b/jdk/test/java/nio/Buffer/BasicChar.java
index a0df9fc..9f3c5e4 100644
--- a/jdk/test/java/nio/Buffer/BasicChar.java
+++ b/jdk/test/java/nio/Buffer/BasicChar.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final char[] VALUES = {
+ Character.MIN_VALUE,
+ (char) -1,
+ (char) 0,
+ (char) 1,
+ Character.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(CharBuffer b) {
int n = b.capacity();
char v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ CharBuffer xb, CharBuffer yb,
+ char x, char y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (char x : VALUES) {
+ CharBuffer xb = CharBuffer.wrap(new char[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (char y : VALUES) {
+ CharBuffer yb = CharBuffer.wrap(new char[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Character.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for CharBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for CharBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicDouble.java b/jdk/test/java/nio/Buffer/BasicDouble.java
index a627d0e..97f5fa2 100644
--- a/jdk/test/java/nio/Buffer/BasicDouble.java
+++ b/jdk/test/java/nio/Buffer/BasicDouble.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final double[] VALUES = {
+ Double.MIN_VALUE,
+ (double) -1,
+ (double) 0,
+ (double) 1,
+ Double.MAX_VALUE,
+
+
+
+
+
+
+
+ Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY,
+ Double.NaN,
+ (double) -0.0,
+
+ };
+
private static void relGet(DoubleBuffer b) {
int n = b.capacity();
double v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ DoubleBuffer xb, DoubleBuffer yb,
+ double x, double y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (double x : VALUES) {
+ DoubleBuffer xb = DoubleBuffer.wrap(new double[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (double y : VALUES) {
+ DoubleBuffer yb = DoubleBuffer.wrap(new double[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Double.compare(x, y)) {
+
+
+
+
+ if (x == 0.0 && y == 0.0) continue;
+
+ fail("Incorrect results for DoubleBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for DoubleBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicFloat.java b/jdk/test/java/nio/Buffer/BasicFloat.java
index 730dcbe..46bdfe1 100644
--- a/jdk/test/java/nio/Buffer/BasicFloat.java
+++ b/jdk/test/java/nio/Buffer/BasicFloat.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final float[] VALUES = {
+ Float.MIN_VALUE,
+ (float) -1,
+ (float) 0,
+ (float) 1,
+ Float.MAX_VALUE,
+
+ Float.NEGATIVE_INFINITY,
+ Float.POSITIVE_INFINITY,
+ Float.NaN,
+ (float) -0.0,
+
+
+
+
+
+
+
+ };
+
private static void relGet(FloatBuffer b) {
int n = b.capacity();
float v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ FloatBuffer xb, FloatBuffer yb,
+ float x, float y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (float x : VALUES) {
+ FloatBuffer xb = FloatBuffer.wrap(new float[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (float y : VALUES) {
+ FloatBuffer yb = FloatBuffer.wrap(new float[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Float.compare(x, y)) {
+
+ if (x == 0.0 && y == 0.0) continue;
+
+
+
+
+ fail("Incorrect results for FloatBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for FloatBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicInt.java b/jdk/test/java/nio/Buffer/BasicInt.java
index b20e4bb..478debd 100644
--- a/jdk/test/java/nio/Buffer/BasicInt.java
+++ b/jdk/test/java/nio/Buffer/BasicInt.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final int[] VALUES = {
+ Integer.MIN_VALUE,
+ (int) -1,
+ (int) 0,
+ (int) 1,
+ Integer.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(IntBuffer b) {
int n = b.capacity();
int v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ IntBuffer xb, IntBuffer yb,
+ int x, int y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (int x : VALUES) {
+ IntBuffer xb = IntBuffer.wrap(new int[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (int y : VALUES) {
+ IntBuffer yb = IntBuffer.wrap(new int[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Integer.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for IntBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for IntBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicLong.java b/jdk/test/java/nio/Buffer/BasicLong.java
index 0d4c568..0abc7cd 100644
--- a/jdk/test/java/nio/Buffer/BasicLong.java
+++ b/jdk/test/java/nio/Buffer/BasicLong.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final long[] VALUES = {
+ Long.MIN_VALUE,
+ (long) -1,
+ (long) 0,
+ (long) 1,
+ Long.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(LongBuffer b) {
int n = b.capacity();
long v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ LongBuffer xb, LongBuffer yb,
+ long x, long y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (long x : VALUES) {
+ LongBuffer xb = LongBuffer.wrap(new long[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (long y : VALUES) {
+ LongBuffer yb = LongBuffer.wrap(new long[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Long.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for LongBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for LongBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/BasicShort.java b/jdk/test/java/nio/Buffer/BasicShort.java
index 58e5a3e..861d356 100644
--- a/jdk/test/java/nio/Buffer/BasicShort.java
+++ b/jdk/test/java/nio/Buffer/BasicShort.java
@@ -38,6 +38,26 @@
extends Basic
{
+ private static final short[] VALUES = {
+ Short.MIN_VALUE,
+ (short) -1,
+ (short) 0,
+ (short) 1,
+ Short.MAX_VALUE,
+
+
+
+
+
+
+
+
+
+
+
+
+ };
+
private static void relGet(ShortBuffer b) {
int n = b.capacity();
short v;
@@ -309,6 +329,12 @@
+ private static void fail(String problem,
+ ShortBuffer xb, ShortBuffer yb,
+ short x, short y) {
+ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
+ }
+
private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
boolean caught = false;
try {
@@ -522,6 +548,42 @@
if (b.compareTo(b2) <= 0)
fail("Comparison to lesser buffer <= 0", b, b2);
+ // Check equals and compareTo with interesting values
+ for (short x : VALUES) {
+ ShortBuffer xb = ShortBuffer.wrap(new short[] { x });
+ if (xb.compareTo(xb) != 0) {
+ fail("compareTo not reflexive", xb, xb, x, x);
+ }
+ if (! xb.equals(xb)) {
+ fail("equals not reflexive", xb, xb, x, x);
+ }
+ for (short y : VALUES) {
+ ShortBuffer yb = ShortBuffer.wrap(new short[] { y });
+ if (xb.compareTo(yb) != - yb.compareTo(xb)) {
+ fail("compareTo not anti-symmetric",
+ xb, yb, x, y);
+ }
+ if ((xb.compareTo(yb) == 0) != xb.equals(yb)) {
+ fail("compareTo inconsistent with equals",
+ xb, yb, x, y);
+ }
+ if (xb.compareTo(yb) != Short.compare(x, y)) {
+
+
+
+
+
+
+ fail("Incorrect results for ShortBuffer.compareTo",
+ xb, yb, x, y);
+ }
+ if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) {
+ fail("Incorrect results for ShortBuffer.equals",
+ xb, yb, x, y);
+ }
+ }
+ }
+
// Sub, dup
relPut(b);
diff --git a/jdk/test/java/nio/Buffer/genBasic.sh b/jdk/test/java/nio/Buffer/genBasic.sh
index da5fca5..009cf2d 100644
--- a/jdk/test/java/nio/Buffer/genBasic.sh
+++ b/jdk/test/java/nio/Buffer/genBasic.sh
@@ -36,5 +36,3 @@
gen long Long Long
gen float Float Float
gen double Double Double
-
-rm -rf build