Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
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;
Expand Down Expand Up @@ -95,19 +97,26 @@
* <cite>IEEE Standard for Floating-Point Arithmetic</cite></a>
*/

// 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<Float16> {
/** @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
/**
Expand Down Expand Up @@ -147,8 +156,14 @@ private Float16(short bits) {
*/
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);

/**
Expand Down Expand Up @@ -316,10 +331,10 @@ public static Float16 valueOf(int value) {
* @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. +/-
Expand Down Expand Up @@ -427,9 +442,8 @@ public static Float16 valueOf(double d) {
// 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) ));
}

/**
Expand Down Expand Up @@ -468,7 +482,7 @@ public static Float16 valueOf(String s) throws NumberFormatException {
// 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)) {
Expand Down Expand Up @@ -899,7 +913,7 @@ public int hashCode() {
*/
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);
}

Expand Down Expand Up @@ -946,7 +960,7 @@ public static short float16ToRawShortBits(Float16 f16) {
*/
public static short float16ToShortBits(Float16 f16) {
if (isNaN(f16)) {
return Float16.NaN.value;
return NaN.value;
}
return f16.value;
}
Expand Down Expand Up @@ -1531,8 +1545,8 @@ public static int getExponent(Float16 f16) {
*/
/*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;
}

/**
Expand Down Expand Up @@ -1563,10 +1577,10 @@ public static Float16 ulp(Float16 f16) {
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));
Expand Down Expand Up @@ -1687,8 +1701,7 @@ public static Float16 scalb(Float16 v, int scaleFactor) {
// 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);
Expand Down Expand Up @@ -1725,9 +1738,8 @@ public static Float16 scalb(Float16 v, int scaleFactor) {
* @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)));
}

/**
Expand Down