From 4ca3ab62759b366fd3e0b2267925f1fa70f057b7 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 7 Oct 2025 16:41:45 +0000 Subject: [PATCH] 8369123: Still more small Float16 refactorings Reviewed-by: rgiulietti --- .../classes/jdk/incubator/vector/Float16.java | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) 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))); } /**