diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java
index a564cdfed0f..fe2a6bf5580 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java
@@ -35,6 +35,8 @@ import static jdk.incubator.vector.Float16Consts.SIGN_BIT_MASK;
import static jdk.incubator.vector.Float16Consts.EXP_BIT_MASK;
import static jdk.incubator.vector.Float16Consts.SIGNIF_BIT_MASK;
import static jdk.incubator.vector.Float16Consts.MAG_BIT_MASK;
+import static jdk.incubator.vector.Float16Consts.EXP_BIAS;
+import static jdk.incubator.vector.Float16Consts.SIGNIFICAND_WIDTH;
import static java.lang.Float.float16ToFloat;
import static java.lang.Float.floatToFloat16;
@@ -95,19 +97,26 @@ import jdk.internal.vm.vector.Float16Math;
* IEEE Standard for Floating-Point Arithmetic
*/
-// Currently Float16 is a value-based class and in future it is
+// Currently Float16 is a value-based class and in the future it is
// expected to be aligned with Value Classes and Object as described in
// JEP-401 (https://openjdk.org/jeps/401).
@jdk.internal.ValueBased
public final class Float16
extends Number
implements Comparable {
- /** @serial */
+
+ /**
+ * Primitive {@code short} field to hold the bits of the {@code Float16}.
+ * @serial
+ */
private final short value;
+
private static final long serialVersionUID = 16; // May not be needed when a value class?
// Functionality for future consideration:
- // IEEEremainder / remainder operator remainder
+ // IEEEremainder and separate % operator remainder (which are
+ // defined to use different rounding modes, see JLS sections 15.4
+ // and 15.17.3).
// Do *not* define any public constructors
/**
@@ -147,8 +156,14 @@ public final class Float16
*/
public static final Float16 NaN = valueOf(Float.NaN);
+ /**
+ * A constant holding a zero (0.0) of type {@code Float16}.
+ */
private static final Float16 ZERO = valueOf(0);
+ /**
+ * A constant holding a one (1.0) of type {@code Float16}.
+ */
private static final Float16 ONE = valueOf(1);
/**
@@ -316,10 +331,10 @@ public final class Float16
* @param value a {@code long} value.
*/
public static Float16 valueOf(long value) {
- if (value <= -65_520L) { // -(Float16.MAX_VALUE + Float16.ulp(Float16.MAX_VALUE) / 2)
+ if (value <= -65_520L) { // -(MAX_VALUE + ulp(MAX_VALUE) / 2)
return NEGATIVE_INFINITY;
} else {
- if (value >= 65_520L) { // Float16.MAX_VALUE + Float16.ulp(Float16.MAX_VALUE) / 2
+ if (value >= 65_520L) { // MAX_VALUE + ulp(MAX_VALUE) / 2
return POSITIVE_INFINITY;
}
// Remaining range of long, the integers in approx. +/-
@@ -427,9 +442,8 @@ public final class Float16
// to implement a carry out from rounding the significand.
assert (0xf800 & signif_bits) == 0x0;
- // Exponent bias adjust in the representation is equal to MAX_EXPONENT.
return new Float16((short)(sign_bit |
- ( ((exp + MAX_EXPONENT) << (PRECISION - 1)) + signif_bits ) ));
+ ( ((exp + EXP_BIAS) << (PRECISION - 1)) + signif_bits) ));
}
/**
@@ -468,7 +482,7 @@ public final class Float16
// characters rather than codepoints.
if (trialResult == 0.0 // handles signed zeros
- || Math.abs(trialResult) > (65504.0 + 32.0) || // Float.MAX_VALUE + ulp(MAX_VALUE),
+ || Math.abs(trialResult) > (65504.0 + 32.0) || // MAX_VALUE + ulp(MAX_VALUE),
// handles infinities too
Double.isNaN(trialResult) ||
noDoubleRoundingToFloat16(trialResult)) {
@@ -899,7 +913,7 @@ public final class Float16
*/
public static int hashCode(Float16 value) {
// Use bit-pattern of canonical NaN for hashing.
- Float16 f16 = isNaN(value) ? Float16.NaN : value;
+ Float16 f16 = isNaN(value) ? NaN : value;
return (int)float16ToRawShortBits(f16);
}
@@ -946,7 +960,7 @@ public final class Float16
*/
public static short float16ToShortBits(Float16 f16) {
if (isNaN(f16)) {
- return Float16.NaN.value;
+ return NaN.value;
}
return f16.value;
}
@@ -1531,8 +1545,8 @@ public final class Float16
*/
/*package*/ static int getExponent0(short bits) {
// package private to be usable in java.lang.Float.
- int bin16ExpBits = 0x0000_7c00 & bits; // Five exponent bits.
- return (bin16ExpBits >> (PRECISION - 1)) - 15;
+ int bin16ExpBits = EXP_BIT_MASK & bits; // Five exponent bits.
+ return (bin16ExpBits >> (PRECISION - 1)) - EXP_BIAS;
}
/**
@@ -1563,10 +1577,10 @@ public final class Float16
int exp = getExponent(f16);
return switch(exp) {
- case MAX_EXPONENT + 1 -> abs(f16); // NaN or infinity
- case MIN_EXPONENT - 1 -> Float16.MIN_VALUE; // zero or subnormal
+ case MAX_EXPONENT + 1 -> abs(f16); // NaN or infinity
+ case MIN_EXPONENT - 1 -> MIN_VALUE; // zero or subnormal
default -> {
- assert exp <= MAX_EXPONENT && exp >= MIN_EXPONENT;
+ assert exp <= MAX_EXPONENT && exp >= MIN_EXPONENT: "Out of range exponent";
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
// Let float -> float16 conversion handle encoding issues.
yield scalb(ONE, exp - (PRECISION - 1));
@@ -1687,8 +1701,7 @@ public final class Float16
// nonzero value by it would be guaranteed to over or
// underflow; due to rounding, scaling down takes an
// additional power of two which is reflected here
- final int MAX_SCALE = Float16.MAX_EXPONENT + -Float16.MIN_EXPONENT +
- Float16Consts.SIGNIFICAND_WIDTH + 1;
+ final int MAX_SCALE = MAX_EXPONENT + -MIN_EXPONENT + SIGNIFICAND_WIDTH + 1;
// Make sure scaling factor is in a reasonable range
scaleFactor = Math.clamp(scaleFactor, -MAX_SCALE, MAX_SCALE);
@@ -1725,9 +1738,8 @@ public final class Float16
* @see Math#copySign(double, double)
*/
public static Float16 copySign(Float16 magnitude, Float16 sign) {
- return shortBitsToFloat16((short) ((float16ToRawShortBits(sign) & SIGN_BIT_MASK) |
- (float16ToRawShortBits(magnitude) &
- (EXP_BIT_MASK | SIGNIF_BIT_MASK) )));
+ return shortBitsToFloat16((short)((float16ToRawShortBits(sign) & SIGN_BIT_MASK) |
+ (float16ToRawShortBits(magnitude) & MAG_BIT_MASK)));
}
/**