All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP
@ 2018-05-02 15:43 Alex Bennée
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions Alex Bennée
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Alex Bennée @ 2018-05-02 15:43 UTC (permalink / raw)
  To: peter.maydell; +Cc: richard.henderson, qemu-arm, qemu-devel, Alex Bennée

Hi,

This is a more polished version of the re-factoring of the softfloat
fcvt code. I've split apart the fixes for ARM alternative
half-precision format for easier review. Rather than rely on some
questionable hacks it introduces a new FloatFmt to allow cleaner
handling of the differences in the common code. If there are other
alternative floating point formats they can follow a similar approach.

I've included the test case for reference although I expect it to be
merged with my tcg-testing revival code which has the rest of the
build and test machinery for the test case.

checkpatch dumps a bunch of false-positives as it doesn't like
scientific notation for floats or inline assembler used in the test
case.

Cheers,

Alex Bennée (3):
  fpu/softfloat: re-factor float to float conversions
  fpu/softfloat: support ARM Alternative half-precision
  tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM)

 fpu/softfloat-specialize.h |   40 -
 fpu/softfloat.c            |  524 +++------
 include/fpu/softfloat.h    |    8 +-
 tests/tcg/aarch64/fcvt.c   |  296 +++++
 tests/tcg/aarch64/fcvt.ref | 2138 ++++++++++++++++++++++++++++++++++++
 5 files changed, 2588 insertions(+), 418 deletions(-)
 create mode 100644 tests/tcg/aarch64/fcvt.c
 create mode 100644 tests/tcg/aarch64/fcvt.ref

-- 
2.17.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions
  2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
@ 2018-05-02 15:43 ` Alex Bennée
  2018-05-02 16:26   ` Richard Henderson
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision Alex Bennée
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Alex Bennée @ 2018-05-02 15:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: richard.henderson, qemu-arm, qemu-devel, Alex Bennée,
	Aurelien Jarno

This allows us to delete a lot of additional boilerplate code which is
no longer needed. Currently the ieee flag is ignored (everything is
assumed to be ieee). Handling for ARM AHP will be in the next patch.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v2
  - pass FloatFmt to float_to_float instead of sizes
  - split AHP handling to another patch
  - use rth's suggested re-packing (+ setting .exp)
---
 fpu/softfloat-specialize.h |  40 ----
 fpu/softfloat.c            | 443 +++++++------------------------------
 include/fpu/softfloat.h    |   8 +-
 3 files changed, 88 insertions(+), 403 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 27834af0de..a20b440159 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -293,46 +293,6 @@ float16 float16_maybe_silence_nan(float16 a_, float_status *status)
     return a_;
 }
 
-/*----------------------------------------------------------------------------
-| Returns the result of converting the half-precision floating-point NaN
-| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float16ToCommonNaN(float16 a, float_status *status)
-{
-    commonNaNT z;
-
-    if (float16_is_signaling_nan(a, status)) {
-        float_raise(float_flag_invalid, status);
-    }
-    z.sign = float16_val(a) >> 15;
-    z.low = 0;
-    z.high = ((uint64_t) float16_val(a)) << 54;
-    return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the half-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float16 commonNaNToFloat16(commonNaNT a, float_status *status)
-{
-    uint16_t mantissa = a.high >> 54;
-
-    if (status->default_nan_mode) {
-        return float16_default_nan(status);
-    }
-
-    if (mantissa) {
-        return make_float16(((((uint16_t) a.sign) << 15)
-                             | (0x1F << 10) | mantissa));
-    } else {
-        return float16_default_nan(status);
-    }
-}
-
 #ifdef NO_SIGNALING_NANS
 int float32_is_quiet_nan(float32 a_, float_status *status)
 {
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 70e0c40a1c..28b9f4f79b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1194,6 +1194,90 @@ float64 float64_div(float64 a, float64 b, float_status *status)
     return float64_round_pack_canonical(pr, status);
 }
 
+/*
+ * Float to Float conversions
+ *
+ * Returns the result of converting one float format to another. The
+ * conversion is performed according to the IEC/IEEE Standard for
+ * Binary Floating-Point Arithmetic.
+ *
+ * The float_to_float helper only needs to take care of raising
+ * invalid exceptions and handling the conversion on NaNs.
+ */
+
+static FloatParts float_to_float(FloatParts a,
+                                 const FloatFmt *srcf, const FloatFmt *dstf,
+                                 float_status *s)
+{
+    if (is_nan(a.cls)) {
+
+        if (is_snan(a.cls)) {
+            s->float_exception_flags |= float_flag_invalid;
+        }
+
+        if (s->default_nan_mode) {
+            a.cls = float_class_dnan;
+            return a;
+        }
+
+        /*
+         * Our only option now is to "re-pack" the NaN. As the
+         * canonilization process doesn't mess with fraction bits for
+         * NaNs we do it all here. We also reset a.exp to the
+         * destination format exp_max as the maybe_silence_nan code
+         * assumes it is correct (which is would be for non-conversions).
+         */
+        a.frac = a.frac << (64 - srcf->frac_size) >> (64 - dstf->frac_size);
+        a.exp = dstf->exp_max;
+        a.cls = float_class_msnan;
+    }
+
+    return a;
+}
+
+float32 float16_to_float32(float16 a, bool ieee, float_status *s)
+{
+    FloatParts p = float16_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float16_params, &float32_params, s);
+    return float32_round_pack_canonical(pr, s);
+}
+
+float64 float16_to_float64(float16 a, bool ieee, float_status *s)
+{
+    FloatParts p = float16_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float16_params, &float64_params, s);
+    return float64_round_pack_canonical(pr, s);
+}
+
+float16 float32_to_float16(float32 a, bool ieee, float_status *s)
+{
+    FloatParts p = float32_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float32_params, &float16_params, s);
+    return float16_round_pack_canonical(pr, s);
+}
+
+float64 float32_to_float64(float32 a, float_status *s)
+{
+    FloatParts p = float32_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float32_params, &float64_params, s);
+    return float64_round_pack_canonical(pr, s);
+}
+
+float16 float64_to_float16(float64 a, bool ieee, float_status *s)
+{
+    FloatParts p = float64_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float64_params, &float16_params, s);
+    return float16_round_pack_canonical(pr, s);
+}
+
+float32 float64_to_float32(float64 a, float_status *s)
+{
+    FloatParts p = float64_unpack_canonical(a, s);
+    FloatParts pr = float_to_float(p, &float64_params, &float32_params, s);
+    return float32_round_pack_canonical(pr, s);
+}
+
+
 /*
  * Rounds the floating-point value `a' to an integer, and returns the
  * result as a floating-point value. The operation is performed
@@ -3142,41 +3226,6 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
     return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status);
 }
 
-
-
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format.  The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float32_to_float64(float32 a, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint32_t aSig;
-    a = float32_squash_input_denormal(a, status);
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    if ( aExp == 0xFF ) {
-        if (aSig) {
-            return commonNaNToFloat64(float32ToCommonNaN(a, status), status);
-        }
-        return packFloat64( aSign, 0x7FF, 0 );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-        --aExp;
-    }
-    return packFloat64( aSign, aExp + 0x380, ( (uint64_t) aSig )<<29 );
-
-}
-
 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
@@ -3695,173 +3744,6 @@ int float32_unordered_quiet(float32 a, float32 b, float_status *status)
     return 0;
 }
 
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the single-precision floating-point format.  The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float64_to_float32(float64 a, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint64_t aSig;
-    uint32_t zSig;
-    a = float64_squash_input_denormal(a, status);
-
-    aSig = extractFloat64Frac( a );
-    aExp = extractFloat64Exp( a );
-    aSign = extractFloat64Sign( a );
-    if ( aExp == 0x7FF ) {
-        if (aSig) {
-            return commonNaNToFloat32(float64ToCommonNaN(a, status), status);
-        }
-        return packFloat32( aSign, 0xFF, 0 );
-    }
-    shift64RightJamming( aSig, 22, &aSig );
-    zSig = aSig;
-    if ( aExp || zSig ) {
-        zSig |= 0x40000000;
-        aExp -= 0x381;
-    }
-    return roundAndPackFloat32(aSign, aExp, zSig, status);
-
-}
-
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| half-precision floating-point value, returning the result.  After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result.  This means that any integer portion of `zSig'
-| will be added into the exponent.  Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-static float16 packFloat16(flag zSign, int zExp, uint16_t zSig)
-{
-    return make_float16(
-        (((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper half-precision floating-
-| point value corresponding to the abstract input.  Ordinarily, the abstract
-| value is simply rounded and packed into the half-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly.  However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned.  If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal half-
-| precision floating-point number.
-| The `ieee' flag indicates whether to use IEEE standard half precision, or
-| ARM-style "alternative representation", which omits the NaN and Inf
-| encodings in order to raise the maximum representable exponent by one.
-|     The input significand `zSig' has its binary point between bits 22
-| and 23, which is 13 bits to the left of the usual location.  This shifted
-| significand must be normalized or smaller.  If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding.  In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| Note the slightly odd position of the binary point in zSig compared with the
-| other roundAndPackFloat functions. This should probably be fixed if we
-| need to implement more float16 routines than just conversion.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float16 roundAndPackFloat16(flag zSign, int zExp,
-                                   uint32_t zSig, flag ieee,
-                                   float_status *status)
-{
-    int maxexp = ieee ? 29 : 30;
-    uint32_t mask;
-    uint32_t increment;
-    bool rounding_bumps_exp;
-    bool is_tiny = false;
-
-    /* Calculate the mask of bits of the mantissa which are not
-     * representable in half-precision and will be lost.
-     */
-    if (zExp < 1) {
-        /* Will be denormal in halfprec */
-        mask = 0x00ffffff;
-        if (zExp >= -11) {
-            mask >>= 11 + zExp;
-        }
-    } else {
-        /* Normal number in halfprec */
-        mask = 0x00001fff;
-    }
-
-    switch (status->float_rounding_mode) {
-    case float_round_nearest_even:
-        increment = (mask + 1) >> 1;
-        if ((zSig & mask) == increment) {
-            increment = zSig & (increment << 1);
-        }
-        break;
-    case float_round_ties_away:
-        increment = (mask + 1) >> 1;
-        break;
-    case float_round_up:
-        increment = zSign ? 0 : mask;
-        break;
-    case float_round_down:
-        increment = zSign ? mask : 0;
-        break;
-    default: /* round_to_zero */
-        increment = 0;
-        break;
-    }
-
-    rounding_bumps_exp = (zSig + increment >= 0x01000000);
-
-    if (zExp > maxexp || (zExp == maxexp && rounding_bumps_exp)) {
-        if (ieee) {
-            float_raise(float_flag_overflow | float_flag_inexact, status);
-            return packFloat16(zSign, 0x1f, 0);
-        } else {
-            float_raise(float_flag_invalid, status);
-            return packFloat16(zSign, 0x1f, 0x3ff);
-        }
-    }
-
-    if (zExp < 0) {
-        /* Note that flush-to-zero does not affect half-precision results */
-        is_tiny =
-            (status->float_detect_tininess == float_tininess_before_rounding)
-            || (zExp < -1)
-            || (!rounding_bumps_exp);
-    }
-    if (zSig & mask) {
-        float_raise(float_flag_inexact, status);
-        if (is_tiny) {
-            float_raise(float_flag_underflow, status);
-        }
-    }
-
-    zSig += increment;
-    if (rounding_bumps_exp) {
-        zSig >>= 1;
-        zExp++;
-    }
-
-    if (zExp < -10) {
-        return packFloat16(zSign, 0, 0);
-    }
-    if (zExp < 0) {
-        zSig >>= -zExp;
-        zExp = 0;
-    }
-    return packFloat16(zSign, zExp, zSig >> 13);
-}
-
 /*----------------------------------------------------------------------------
 | If `a' is denormal and we are in flush-to-zero mode then set the
 | input-denormal exception and return zero. Otherwise just return the value.
@@ -3877,163 +3759,6 @@ float16 float16_squash_input_denormal(float16 a, float_status *status)
     return a;
 }
 
-static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr,
-                                      uint32_t *zSigPtr)
-{
-    int8_t shiftCount = countLeadingZeros32(aSig) - 21;
-    *zSigPtr = aSig << shiftCount;
-    *zExpPtr = 1 - shiftCount;
-}
-
-/* Half precision floats come in two formats: standard IEEE and "ARM" format.
-   The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
-
-float32 float16_to_float32(float16 a, flag ieee, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint32_t aSig;
-
-    aSign = extractFloat16Sign(a);
-    aExp = extractFloat16Exp(a);
-    aSig = extractFloat16Frac(a);
-
-    if (aExp == 0x1f && ieee) {
-        if (aSig) {
-            return commonNaNToFloat32(float16ToCommonNaN(a, status), status);
-        }
-        return packFloat32(aSign, 0xff, 0);
-    }
-    if (aExp == 0) {
-        if (aSig == 0) {
-            return packFloat32(aSign, 0, 0);
-        }
-
-        normalizeFloat16Subnormal(aSig, &aExp, &aSig);
-        aExp--;
-    }
-    return packFloat32( aSign, aExp + 0x70, aSig << 13);
-}
-
-float16 float32_to_float16(float32 a, flag ieee, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint32_t aSig;
-
-    a = float32_squash_input_denormal(a, status);
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    if ( aExp == 0xFF ) {
-        if (aSig) {
-            /* Input is a NaN */
-            if (!ieee) {
-                float_raise(float_flag_invalid, status);
-                return packFloat16(aSign, 0, 0);
-            }
-            return commonNaNToFloat16(
-                float32ToCommonNaN(a, status), status);
-        }
-        /* Infinity */
-        if (!ieee) {
-            float_raise(float_flag_invalid, status);
-            return packFloat16(aSign, 0x1f, 0x3ff);
-        }
-        return packFloat16(aSign, 0x1f, 0);
-    }
-    if (aExp == 0 && aSig == 0) {
-        return packFloat16(aSign, 0, 0);
-    }
-    /* Decimal point between bits 22 and 23. Note that we add the 1 bit
-     * even if the input is denormal; however this is harmless because
-     * the largest possible single-precision denormal is still smaller
-     * than the smallest representable half-precision denormal, and so we
-     * will end up ignoring aSig and returning via the "always return zero"
-     * codepath.
-     */
-    aSig |= 0x00800000;
-    aExp -= 0x71;
-
-    return roundAndPackFloat16(aSign, aExp, aSig, ieee, status);
-}
-
-float64 float16_to_float64(float16 a, flag ieee, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint32_t aSig;
-
-    aSign = extractFloat16Sign(a);
-    aExp = extractFloat16Exp(a);
-    aSig = extractFloat16Frac(a);
-
-    if (aExp == 0x1f && ieee) {
-        if (aSig) {
-            return commonNaNToFloat64(
-                float16ToCommonNaN(a, status), status);
-        }
-        return packFloat64(aSign, 0x7ff, 0);
-    }
-    if (aExp == 0) {
-        if (aSig == 0) {
-            return packFloat64(aSign, 0, 0);
-        }
-
-        normalizeFloat16Subnormal(aSig, &aExp, &aSig);
-        aExp--;
-    }
-    return packFloat64(aSign, aExp + 0x3f0, ((uint64_t)aSig) << 42);
-}
-
-float16 float64_to_float16(float64 a, flag ieee, float_status *status)
-{
-    flag aSign;
-    int aExp;
-    uint64_t aSig;
-    uint32_t zSig;
-
-    a = float64_squash_input_denormal(a, status);
-
-    aSig = extractFloat64Frac(a);
-    aExp = extractFloat64Exp(a);
-    aSign = extractFloat64Sign(a);
-    if (aExp == 0x7FF) {
-        if (aSig) {
-            /* Input is a NaN */
-            if (!ieee) {
-                float_raise(float_flag_invalid, status);
-                return packFloat16(aSign, 0, 0);
-            }
-            return commonNaNToFloat16(
-                float64ToCommonNaN(a, status), status);
-        }
-        /* Infinity */
-        if (!ieee) {
-            float_raise(float_flag_invalid, status);
-            return packFloat16(aSign, 0x1f, 0x3ff);
-        }
-        return packFloat16(aSign, 0x1f, 0);
-    }
-    shift64RightJamming(aSig, 29, &aSig);
-    zSig = aSig;
-    if (aExp == 0 && zSig == 0) {
-        return packFloat16(aSign, 0, 0);
-    }
-    /* Decimal point between bits 22 and 23. Note that we add the 1 bit
-     * even if the input is denormal; however this is harmless because
-     * the largest possible single-precision denormal is still smaller
-     * than the smallest representable half-precision denormal, and so we
-     * will end up ignoring aSig and returning via the "always return zero"
-     * codepath.
-     */
-    zSig |= 0x00800000;
-    aExp -= 0x3F1;
-
-    return roundAndPackFloat16(aSign, aExp, zSig, ieee, status);
-}
-
 /*----------------------------------------------------------------------------
 | Returns the result of converting the double-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 36626a501b..01ef1c6b81 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -211,10 +211,10 @@ float128 uint64_to_float128(uint64_t, float_status *status);
 /*----------------------------------------------------------------------------
 | Software half-precision conversion routines.
 *----------------------------------------------------------------------------*/
-float16 float32_to_float16(float32, flag, float_status *status);
-float32 float16_to_float32(float16, flag, float_status *status);
-float16 float64_to_float16(float64 a, flag ieee, float_status *status);
-float64 float16_to_float64(float16 a, flag ieee, float_status *status);
+float16 float32_to_float16(float32, bool ieee, float_status *status);
+float32 float16_to_float32(float16, bool ieee, float_status *status);
+float16 float64_to_float16(float64 a, bool ieee, float_status *status);
+float64 float16_to_float64(float16 a, bool ieee, float_status *status);
 int16_t float16_to_int16(float16, float_status *status);
 uint16_t float16_to_uint16(float16 a, float_status *status);
 int16_t float16_to_int16_round_to_zero(float16, float_status *status);
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions Alex Bennée
@ 2018-05-02 15:43 ` Alex Bennée
  2018-05-03 18:17   ` Peter Maydell
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 3/3] tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM) Alex Bennée
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Alex Bennée @ 2018-05-02 15:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: richard.henderson, qemu-arm, qemu-devel, Alex Bennée,
	Aurelien Jarno

For float16 ARM supports an alternative half-precision format which
sacrifices the ability to represent NaN/Inf in return for a higher
dynamic range. To support this I've added an additional
FloatFmt (float16_params_ahp).

The new FloatFmt flag (arm_althp) is then used to modify the behaviour
of canonicalize and round_canonical with respect to representation and
exception raising.

Finally the float16_to_floatN and floatN_to_float16 conversion
routines select the new alternative FloatFmt when !ieee.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 fpu/softfloat.c | 97 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 74 insertions(+), 23 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 28b9f4f79b..25a331158f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -234,6 +234,8 @@ typedef struct {
  *   frac_lsb: least significant bit of fraction
  *   fram_lsbm1: the bit bellow the least significant bit (for rounding)
  *   round_mask/roundeven_mask: masks used for rounding
+ * The following optional modifiers are available:
+ *   arm_althp: handle ARM Alternative Half Precision
  */
 typedef struct {
     int exp_size;
@@ -245,6 +247,7 @@ typedef struct {
     uint64_t frac_lsbm1;
     uint64_t round_mask;
     uint64_t roundeven_mask;
+    bool arm_althp;
 } FloatFmt;
 
 /* Expand fields based on the size of exponent and fraction */
@@ -257,12 +260,17 @@ typedef struct {
     .frac_lsb       = 1ull << (DECOMPOSED_BINARY_POINT - F),         \
     .frac_lsbm1     = 1ull << ((DECOMPOSED_BINARY_POINT - F) - 1),   \
     .round_mask     = (1ull << (DECOMPOSED_BINARY_POINT - F)) - 1,   \
-    .roundeven_mask = (2ull << (DECOMPOSED_BINARY_POINT - F)) - 1
+    .roundeven_mask = (2ull << (DECOMPOSED_BINARY_POINT - F)) - 1,
 
 static const FloatFmt float16_params = {
     FLOAT_PARAMS(5, 10)
 };
 
+static const FloatFmt float16_params_ahp = {
+    FLOAT_PARAMS(5, 10)
+    .arm_althp = true
+};
+
 static const FloatFmt float32_params = {
     FLOAT_PARAMS(8, 23)
 };
@@ -326,7 +334,7 @@ static inline float64 float64_pack_raw(FloatParts p)
 static FloatParts canonicalize(FloatParts part, const FloatFmt *parm,
                                float_status *status)
 {
-    if (part.exp == parm->exp_max) {
+    if (part.exp == parm->exp_max && !parm->arm_althp) {
         if (part.frac == 0) {
             part.cls = float_class_inf;
         } else {
@@ -412,8 +420,9 @@ static FloatParts round_canonical(FloatParts p, float_status *s,
 
         exp += parm->exp_bias;
         if (likely(exp > 0)) {
+            bool maybe_inexact = false;
             if (frac & round_mask) {
-                flags |= float_flag_inexact;
+                maybe_inexact = true;
                 frac += inc;
                 if (frac & DECOMPOSED_OVERFLOW_BIT) {
                     frac >>= 1;
@@ -422,14 +431,26 @@ static FloatParts round_canonical(FloatParts p, float_status *s,
             }
             frac >>= frac_shift;
 
-            if (unlikely(exp >= exp_max)) {
-                flags |= float_flag_overflow | float_flag_inexact;
-                if (overflow_norm) {
-                    exp = exp_max - 1;
-                    frac = -1;
-                } else {
-                    p.cls = float_class_inf;
-                    goto do_inf;
+            if (parm->arm_althp) {
+                if (unlikely(exp >= exp_max + 1)) {
+                        flags |= float_flag_invalid;
+                        frac = -1;
+                        exp = exp_max;
+                } else if (maybe_inexact) {
+                    flags |= float_flag_inexact;
+                }
+            } else {
+                if (unlikely(exp >= exp_max)) {
+                    flags |= float_flag_overflow | float_flag_inexact;
+                    if (overflow_norm) {
+                        exp = exp_max - 1;
+                        frac = -1;
+                    } else {
+                        p.cls = float_class_inf;
+                        goto do_inf;
+                    }
+                } else if (maybe_inexact) {
+                    flags |= float_flag_inexact;
                 }
             }
         } else if (s->flush_to_zero) {
@@ -474,7 +495,13 @@ static FloatParts round_canonical(FloatParts p, float_status *s,
     case float_class_inf:
     do_inf:
         exp = exp_max;
-        frac = 0;
+        if (parm->arm_althp) {
+            flags |= float_flag_invalid;
+            /* Alt HP returns result = sign:Ones(M-1) */
+            frac = -1;
+        } else {
+            frac = 0;
+        }
         break;
 
     case float_class_qnan:
@@ -492,12 +519,21 @@ static FloatParts round_canonical(FloatParts p, float_status *s,
     return p;
 }
 
+/* Explicit FloatFmt version */
+static FloatParts float16a_unpack_canonical(const FloatFmt *params,
+                                            float16 f, float_status *s)
+{
+    return canonicalize(float16_unpack_raw(f), params, s);
+}
+
 static FloatParts float16_unpack_canonical(float16 f, float_status *s)
 {
-    return canonicalize(float16_unpack_raw(f), &float16_params, s);
+    return float16a_unpack_canonical(&float16_params, f, s);
 }
 
-static float16 float16_round_pack_canonical(FloatParts p, float_status *s)
+
+static float16 float16a_round_pack_canonical(const FloatFmt *params,
+                                             FloatParts p, float_status *s)
 {
     switch (p.cls) {
     case float_class_dnan:
@@ -505,11 +541,16 @@ static float16 float16_round_pack_canonical(FloatParts p, float_status *s)
     case float_class_msnan:
         return float16_maybe_silence_nan(float16_pack_raw(p), s);
     default:
-        p = round_canonical(p, s, &float16_params);
+        p = round_canonical(p, s, params);
         return float16_pack_raw(p);
     }
 }
 
+static float16 float16_round_pack_canonical(FloatParts p, float_status *s)
+{
+    return float16a_round_pack_canonical(&float16_params, p, s);
+}
+
 static FloatParts float32_unpack_canonical(float32 f, float_status *s)
 {
     return canonicalize(float32_unpack_raw(f), &float32_params, s);
@@ -1235,25 +1276,34 @@ static FloatParts float_to_float(FloatParts a,
     return a;
 }
 
+/*
+ * Currently non-ieee implies ARM Alternative Half Precision handling
+ * for float16 values. If more are needed we'll need to expand the API
+ * into softfloat.
+ */
+
 float32 float16_to_float32(float16 a, bool ieee, float_status *s)
 {
-    FloatParts p = float16_unpack_canonical(a, s);
-    FloatParts pr = float_to_float(p, &float16_params, &float32_params, s);
+    const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
+    FloatParts p = float16a_unpack_canonical(fmt16, a, s);
+    FloatParts pr = float_to_float(p, fmt16, &float32_params, s);
     return float32_round_pack_canonical(pr, s);
 }
 
 float64 float16_to_float64(float16 a, bool ieee, float_status *s)
 {
-    FloatParts p = float16_unpack_canonical(a, s);
-    FloatParts pr = float_to_float(p, &float16_params, &float64_params, s);
+    const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
+    FloatParts p = float16a_unpack_canonical(fmt16, a, s);
+    FloatParts pr = float_to_float(p, fmt16, &float64_params, s);
     return float64_round_pack_canonical(pr, s);
 }
 
 float16 float32_to_float16(float32 a, bool ieee, float_status *s)
 {
+    const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
     FloatParts p = float32_unpack_canonical(a, s);
-    FloatParts pr = float_to_float(p, &float32_params, &float16_params, s);
-    return float16_round_pack_canonical(pr, s);
+    FloatParts pr = float_to_float(p, &float32_params, fmt16, s);
+    return float16a_round_pack_canonical(fmt16, pr, s);
 }
 
 float64 float32_to_float64(float32 a, float_status *s)
@@ -1265,9 +1315,10 @@ float64 float32_to_float64(float32 a, float_status *s)
 
 float16 float64_to_float16(float64 a, bool ieee, float_status *s)
 {
+    const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
     FloatParts p = float64_unpack_canonical(a, s);
-    FloatParts pr = float_to_float(p, &float64_params, &float16_params, s);
-    return float16_round_pack_canonical(pr, s);
+    FloatParts pr = float_to_float(p, &float64_params, fmt16, s);
+    return float16a_round_pack_canonical(fmt16, pr, s);
 }
 
 float32 float64_to_float32(float64 a, float_status *s)
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH v2 3/3] tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM)
  2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions Alex Bennée
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision Alex Bennée
@ 2018-05-02 15:43 ` Alex Bennée
  2018-05-02 15:54 ` [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP no-reply
  2018-05-02 16:28 ` Richard Henderson
  4 siblings, 0 replies; 12+ messages in thread
From: Alex Bennée @ 2018-05-02 15:43 UTC (permalink / raw)
  To: peter.maydell; +Cc: richard.henderson, qemu-arm, qemu-devel, Alex Bennée

This runs through the usual float to float conversions and crucially
also runs with ARM Alternative Half Precision Format.

[!UPSTREAM: will be in next revision of tcg-tests-revival]

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v4
  - add fcvt.ref and check results against it
  - fix single_to_half, single_to_double conversions
  - properly toggle AHP mode (fpsr->fpcr)
  - more values around the AHP margins
---
 tests/tcg/aarch64/fcvt.c   |  296 +++++
 tests/tcg/aarch64/fcvt.ref | 2138 ++++++++++++++++++++++++++++++++++++
 2 files changed, 2434 insertions(+)
 create mode 100644 tests/tcg/aarch64/fcvt.c
 create mode 100644 tests/tcg/aarch64/fcvt.ref

diff --git a/tests/tcg/aarch64/fcvt.c b/tests/tcg/aarch64/fcvt.c
new file mode 100644
index 0000000000..8f720dfa9f
--- /dev/null
+++ b/tests/tcg/aarch64/fcvt.c
@@ -0,0 +1,296 @@
+/*
+ * Test Floating Point Conversion
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static char flag_str[256];
+
+static char *get_flag_state(int flags)
+{
+    if (flags) {
+        snprintf(flag_str, sizeof(flag_str), "%s %s %s %s %s",
+                 flags & FE_OVERFLOW ? "OVERFLOW" : "",
+                 flags & FE_UNDERFLOW ? "UNDERFLOW" : "",
+                 flags & FE_DIVBYZERO ? "DIV0" : "",
+                 flags & FE_INEXACT ? "INEXACT" : "",
+                 flags & FE_INVALID ? "INVALID" : "");
+    } else {
+        snprintf(flag_str, sizeof(flag_str), "OK");
+    }
+
+    return flag_str;
+}
+
+static void print_double_number(int i, double num)
+{
+    uint64_t double_as_hex = *(uint64_t *) &num;
+    int flags = fetestexcept(FE_ALL_EXCEPT);
+    char *fstr = get_flag_state(flags);
+
+    printf("%02d DOUBLE: %02.20e / %#020lx  (%#x => %s)\n",
+           i, num, double_as_hex, flags, fstr);
+}
+
+static void print_single_number(int i, float num)
+{
+    uint32_t single_as_hex = *(uint32_t *) &num;
+    int flags = fetestexcept(FE_ALL_EXCEPT);
+    char *fstr = get_flag_state(flags);
+
+    printf("%02d SINGLE: %02.20e / %#010x  (%#x => %s)\n",
+           i, num, single_as_hex, flags, fstr);
+}
+
+static void print_half_number(int i, uint16_t num)
+{
+    int flags = fetestexcept(FE_ALL_EXCEPT);
+    char *fstr = get_flag_state(flags);
+
+    printf("%02d   HALF: %#04x  (%#x => %s)\n",
+           i, num, flags, fstr);
+}
+
+float single_numbers[] = { -FLT_MAX,
+                           -1.111E+31,
+                           -1.111E+30,
+                           -1.08700982e-12,
+                           -1.78051176e-20,
+                           -FLT_MIN,
+                           0.0,
+                           FLT_MIN,
+                           5.96046E-8, /* min positive FP16 subnormal */
+                           6.09756E-5, /* max subnormal FP16 */
+                           6.10352E-5, /* min positive normal FP16 */
+                           1.0,
+                           1.0009765625, /* smallest float after 1.0 FP16 */
+                           2.0,
+                           M_E, M_PI,
+                           65503.0,
+                           65504.0, /* max FP16 */
+                           65505.0,
+                           131007.0,
+                           131008.0, /* max AFP */
+                           131009.0,
+                           1.111E+30,
+                           FLT_MAX };
+
+static void convert_single_to_half(void)
+{
+    int i;
+
+    printf("Converting single-precision to half-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
+        float input = single_numbers[i];
+        uint16_t output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_single_number(i, input);
+        asm("fcvt %h0, %s1" : "=w" (output) : "x" (input));
+        print_half_number(i, output);
+    }
+}
+
+static void convert_single_to_double(void)
+{
+    int i;
+
+    printf("Converting single-precision to double-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
+        float input = single_numbers[i];
+        uint64_t output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_single_number(i, input);
+        asm("fcvt %d0, %s1" : "=w" (output) : "x" (input));
+        print_double_number(i, output);
+    }
+}
+
+double double_numbers[] = { -DBL_MAX,
+                            -FLT_MAX-1.0,
+                            -FLT_MAX,
+                            -1.111E+31,
+                            -1.111E+30, /* half prec */
+                            -2.0, -1.0,
+                            -DBL_MIN,
+                            -FLT_MIN,
+                            0.0,
+                            FLT_MIN,
+                            5.96046E-8, /* min positive FP16 subnormal */
+                            6.09756E-5, /* max subnormal FP16 */
+                            6.10352E-5, /* min positive normal FP16 */
+                            1.0,
+                            1.0009765625, /* smallest float after 1.0 FP16 */
+                            DBL_MIN,
+                            1.3789972848607228e-308,
+                            1.4914738736681624e-308,
+                            1.0, 2.0,
+                            M_E, M_PI,
+                            65503.0,
+                            65504.0, /* max FP16 */
+                            65505.0,
+                            131007.0,
+                            131008.0, /* max AFP */
+                            131009.0,
+                            FLT_MAX,
+                            FLT_MAX + 1.0,
+                            DBL_MAX };
+
+static void convert_double_to_half(void)
+{
+    int i;
+
+    printf("Converting double-precision to half-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
+        double input = double_numbers[i];
+        uint16_t output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_double_number(i, input);
+
+        /* as we don't have _Float16 support */
+        asm("fcvt %h0, %d1" : "=w" (output) : "x" (input));
+        print_half_number(i, output);
+    }
+}
+
+static void convert_double_to_single(void)
+{
+    int i;
+
+    printf("Converting double-precision to single-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
+        double input = double_numbers[i];
+        uint32_t output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_double_number(i, input);
+
+        asm("fcvt %s0, %d1" : "=w" (output) : "x" (input));
+
+        print_single_number(i, output);
+    }
+}
+
+/* no handy defines for these numbers */
+uint16_t half_numbers[] = {
+    0xffff, /* -NaN / AHP -Max */
+    0xfcff, /* -NaN / AHP */
+    0xfc01, /* -NaN / AHP */
+    0xfc00, /* -Inf */
+    0xfbff, /* -Max */
+    0xc000, /* -2 */
+    0xbc00, /* -1 */
+    0x8001, /* -MIN subnormal */
+    0x8000, /* -0 */
+    0x0000, /* +0 */
+    0x0001, /* MIN subnormal */
+    0x3c00, /* 1 */
+    0x7bff, /* Max */
+    0x7c00, /* Inf */
+    0x7c01, /* NaN / AHP */
+    0x7cff, /* NaN / AHP */
+    0x7fff, /* NaN / AHP +Max*/
+};
+
+static void convert_half_to_double(void)
+{
+    int i;
+
+    printf("Converting half-precision to double-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(half_numbers); ++i) {
+        uint16_t input = half_numbers[i];
+        double output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_half_number(i, input);
+        asm("fcvt %d0, %h1" : "=w" (output) : "x" (input));
+        print_double_number(i, output);
+    }
+}
+
+static void convert_half_to_single(void)
+{
+    int i;
+
+    printf("Converting half-precision to single-precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(half_numbers); ++i) {
+        uint16_t input = half_numbers[i];
+        float output;
+
+        feclearexcept(FE_ALL_EXCEPT);
+
+        print_half_number(i, input);
+        asm("fcvt %s0, %h1" : "=w" (output) : "x" (input));
+        print_single_number(i, output);
+    }
+}
+
+typedef struct {
+    int flag;
+    char *desc;
+} float_mapping;
+
+float_mapping round_flags[] = {
+    { FE_TONEAREST, "to nearest" },
+    { FE_UPWARD, "upwards" },
+    { FE_DOWNWARD, "downwards" },
+    { FE_TOWARDZERO, "to zero" }
+};
+
+int main(int argc, char *argv[argc])
+{
+    int i;
+
+    printf("#### Enabling IEEE Half Precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
+        fesetround(round_flags[i].flag);
+        printf("### Rounding %s\n", round_flags[i].desc);
+        convert_single_to_half();
+        convert_single_to_double();
+        convert_double_to_half();
+        convert_double_to_single();
+        convert_half_to_single();
+        convert_half_to_double();
+    }
+
+    /* And now with ARM alternative FP16 */
+    asm("mrs x1, fpcr\n\t"
+        "orr x1, x1, %[flags]\n\t"
+        "msr fpcr, x1\n\t"
+        : /* no output */ : [flags] "n" (1 << 26) : "x1" );
+
+    printf("#### Enabling ARM Alternative Half Precision\n");
+
+    for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
+        fesetround(round_flags[i].flag);
+        printf("### Rounding %s\n", round_flags[i].desc);
+        convert_single_to_half();
+        convert_single_to_double();
+        convert_double_to_half();
+        convert_double_to_single();
+        convert_half_to_single();
+        convert_half_to_double();
+    }
+
+    return 0;
+}
diff --git a/tests/tcg/aarch64/fcvt.ref b/tests/tcg/aarch64/fcvt.ref
new file mode 100644
index 0000000000..5a5316814c
--- /dev/null
+++ b/tests/tcg/aarch64/fcvt.ref
@@ -0,0 +1,2138 @@
+#### Enabling IEEE Half Precision
+### Rounding to nearest
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x4170  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bff  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x4170  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bff  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026624000000000000e+08 / 0x4e4e0000  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675456000000000000e+09 / 0x4e805bf1  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07853004800000000000e+09 / 0x4e809220  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -nan / 0xffffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -nan / 0xffdfe000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -nan / 0xffc02000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -inf / 0xff800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: inf / 0x7f800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: nan / 0x7fc02000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: nan / 0x7fdfe000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: nan / 0x7fffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -nan / 0x00fffffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -nan / 0x00fffbfc0000000000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -nan / 0x00fff8040000000000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -inf / 0x00fff0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: inf / 0x007ff0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: nan / 0x007ff8040000000000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: nan / 0x007ffbfc0000000000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: nan / 0x007ffffc0000000000  (0 => OK)
+### Rounding upwards
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x400  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x401  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x4170  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4249  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bff  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7c00  (0x14 => OVERFLOW   INEXACT )
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015662e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x400  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x401  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138310e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282844e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238764e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x4170  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4249  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bff  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766502400000000000e+09 / 0x4f730c3b  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962457600000000000e+09 / 0x4f71605e  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015662e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026624000000000000e+08 / 0x4e4e0000  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896384000000000000e+08 / 0x4e61ff01  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912768000000000000e+08 / 0x4e620001  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138310e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282844e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238764e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675456000000000000e+09 / 0x4e805bf1  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07853004800000000000e+09 / 0x4e809220  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -nan / 0xffffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -nan / 0xffdfe000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -nan / 0xffc02000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -inf / 0xff800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: inf / 0x7f800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: nan / 0x7fc02000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: nan / 0x7fdfe000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: nan / 0x7fffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -nan / 0x00fffffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -nan / 0x00fffbfc0000000000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -nan / 0x00fff8040000000000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -inf / 0x00fff0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: inf / 0x007ff0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: nan / 0x007ff8040000000000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: nan / 0x007ffbfc0000000000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: nan / 0x007ffffc0000000000  (0 => OK)
+### Rounding downwards
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730512e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x416f  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bfe  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730512e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+03 DOUBLE: -1.11100000000000007530e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xfc00  (0x14 => OVERFLOW   INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138310e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x416f  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bfe  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007530e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138310e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026560000000000000e+08 / 0x4e4dffff  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675443200000000000e+09 / 0x4e805bf0  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07852992000000000000e+09 / 0x4e80921f  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -nan / 0xffffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -nan / 0xffdfe000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -nan / 0xffc02000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -inf / 0xff800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: inf / 0x7f800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: nan / 0x7fc02000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: nan / 0x7fdfe000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: nan / 0x7fffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -nan / 0x00fffffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -nan / 0x00fffbfc0000000000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -nan / 0x00fff8040000000000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -inf / 0x00fff0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: inf / 0x007ff0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: nan / 0x007ff8040000000000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: nan / 0x007ffbfc0000000000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: nan / 0x007ffffc0000000000  (0 => OK)
+### Rounding to zero
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x416f  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bfe  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7bff  (0x14 => OVERFLOW   INEXACT )
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xfbff  (0x14 => OVERFLOW   INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x416f  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bfe  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026560000000000000e+08 / 0x4e4dffff  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675443200000000000e+09 / 0x4e805bf0  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07852992000000000000e+09 / 0x4e80921f  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -nan / 0xffffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -nan / 0xffdfe000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -nan / 0xffc02000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -inf / 0xff800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: inf / 0x7f800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: nan / 0x7fc02000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: nan / 0x7fdfe000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: nan / 0x7fffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -nan / 0x00fffffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -nan / 0x00fffbfc0000000000  (0x1 =>     INVALID)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -nan / 0x00fff8040000000000  (0x1 =>     INVALID)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -inf / 0x00fff0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: inf / 0x007ff0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: nan / 0x007ff8040000000000  (0x1 =>     INVALID)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: nan / 0x007ffbfc0000000000  (0x1 =>     INVALID)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: nan / 0x007ffffc0000000000  (0 => OK)
+#### Enabling ARM Alternative Half Precision
+### Rounding to nearest
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x4170  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bff  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7fff  (0x10 =>    INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7fff  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7fff  (0x10 =>    INEXACT )
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7fff  (0x1 =>     INVALID)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7fff  (0x1 =>     INVALID)
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xffff  (0x1 =>     INVALID)
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xffff  (0x1 =>     INVALID)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x4170  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bff  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026624000000000000e+08 / 0x4e4e0000  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675456000000000000e+09 / 0x4e805bf1  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07853004800000000000e+09 / 0x4e809220  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -1.31008000000000000000e+05 / 0xc7ffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -8.18560000000000000000e+04 / 0xc79fe000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -6.56000000000000000000e+04 / 0xc7802000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -6.55360000000000000000e+04 / 0xc7800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: 6.55360000000000000000e+04 / 0x47800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: 6.56000000000000000000e+04 / 0x47802000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: 8.18560000000000000000e+04 / 0x479fe000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -1.31008000000000000000e+05 / 0x00c0fffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -8.18560000000000000000e+04 / 0x00c0f3fc0000000000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -6.56000000000000000000e+04 / 0x00c0f0040000000000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -6.55360000000000000000e+04 / 0x00c0f0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: 6.55360000000000000000e+04 / 0x0040f0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: 6.56000000000000000000e+04 / 0x0040f0040000000000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: 8.18560000000000000000e+04 / 0x0040f3fc0000000000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: 1.31008000000000000000e+05 / 0x0040fffc0000000000  (0 => OK)
+### Rounding upwards
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x400  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x401  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x4170  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4249  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bff  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7c00  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7fff  (0x10 =>    INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7fff  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7fff  (0x1 =>     INVALID)
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7fff  (0x1 =>     INVALID)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7fff  (0x1 =>     INVALID)
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750797e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005935e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015673e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851006e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324219e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635273e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859812e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xffff  (0x1 =>     INVALID)
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xffff  (0x1 =>     INVALID)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015662e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x400  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x401  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138310e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282844e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238764e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0x01  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x4170  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4249  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bff  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766502400000000000e+09 / 0x4f730c3b  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962457600000000000e+09 / 0x4f71605e  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750797e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015662e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026624000000000000e+08 / 0x4e4e0000  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994299e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896384000000000000e+08 / 0x4e61ff01  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013665e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912768000000000000e+08 / 0x4e620001  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138310e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282844e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238764e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509080e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675456000000000000e+09 / 0x4e805bf1  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311600e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07853004800000000000e+09 / 0x4e809220  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -1.31008000000000000000e+05 / 0xc7ffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -8.18560000000000000000e+04 / 0xc79fe000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -6.56000000000000000000e+04 / 0xc7802000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -6.55360000000000000000e+04 / 0xc7800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: 6.55360000000000000000e+04 / 0x47800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: 6.56000000000000000000e+04 / 0x47802000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: 8.18560000000000000000e+04 / 0x479fe000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -1.31008000000000000000e+05 / 0x00c0fffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -8.18560000000000000000e+04 / 0x00c0f3fc0000000000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -6.56000000000000000000e+04 / 0x00c0f0040000000000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -6.55360000000000000000e+04 / 0x00c0f0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: 6.55360000000000000000e+04 / 0x0040f0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: 6.56000000000000000000e+04 / 0x0040f0040000000000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: 8.18560000000000000000e+04 / 0x0040f3fc0000000000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: 1.31008000000000000000e+05 / 0x0040fffc0000000000  (0 => OK)
+### Rounding downwards
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730512e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x416f  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bfe  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7ffe  (0x10 =>    INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7fff  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7fff  (0x10 =>    INEXACT )
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7fff  (0x1 =>     INVALID)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7fff  (0x1 =>     INVALID)
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859812e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909791e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635273e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289629e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730512e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750797e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 DOUBLE: -1.11100000000000007530e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xffff  (0x1 =>     INVALID)
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xffff  (0x1 =>     INVALID)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138310e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8001  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x416f  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bfe  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570815e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657868800000000000e+09 / 0x4f7f8000  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859812e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007530e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999085e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138310e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750797e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026560000000000000e+08 / 0x4e4dffff  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675443200000000000e+09 / 0x4e805bf0  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07852992000000000000e+09 / 0x4e80921f  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -1.31008000000000000000e+05 / 0xc7ffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -8.18560000000000000000e+04 / 0xc79fe000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -6.56000000000000000000e+04 / 0xc7802000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -6.55360000000000000000e+04 / 0xc7800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: 6.55360000000000000000e+04 / 0x47800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: 6.56000000000000000000e+04 / 0x47802000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: 8.18560000000000000000e+04 / 0x479fe000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -1.31008000000000000000e+05 / 0x00c0fffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -8.18560000000000000000e+04 / 0x00c0f3fc0000000000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -6.56000000000000000000e+04 / 0x00c0f0040000000000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -6.55360000000000000000e+04 / 0x00c0f0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: 6.55360000000000000000e+04 / 0x0040f0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: 6.56000000000000000000e+04 / 0x0040f0040000000000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: 8.18560000000000000000e+04 / 0x0040f3fc0000000000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: 1.31008000000000000000e+05 / 0x0040fffc0000000000  (0 => OK)
+### Rounding to zero
+Converting single-precision to half-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06   HALF: 0000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10   HALF: 0x400  (0x10 =>    INEXACT )
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12   HALF: 0x3c01  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13   HALF: 0x4000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14   HALF: 0x416f  (0x10 =>    INEXACT )
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15   HALF: 0x4248  (0x10 =>    INEXACT )
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16   HALF: 0x7bfe  (0x10 =>    INEXACT )
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17   HALF: 0x7bff  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18   HALF: 0x7bff  (0x10 =>    INEXACT )
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19   HALF: 0x7ffe  (0x10 =>    INEXACT )
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20   HALF: 0x7fff  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21   HALF: 0x7fff  (0x10 =>    INEXACT )
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22   HALF: 0x7fff  (0x1 =>     INVALID)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23   HALF: 0x7fff  (0x1 =>     INVALID)
+Converting single-precision to double-precision
+00 SINGLE: -3.40282346638528859811e+38 / 0xff7fffff  (0 => OK)
+00 DOUBLE: 1.44070152074213457920e+19 / 0x0043e8fdfffffc0000  (0 => OK)
+01 SINGLE: -1.11100004769645909790e+31 / 0xf30c3a59  (0 => OK)
+01 DOUBLE: 1.42948554489798328320e+19 / 0x0043e8cc30e9640000  (0 => OK)
+02 SINGLE: -1.11100003258488635272e+30 / 0xf1605d5b  (0 => OK)
+02 DOUBLE: 1.42798013491629260800e+19 / 0x0043e8c581756c0000  (0 => OK)
+03 SINGLE: -1.08700982243137289628e-12 / 0xab98fba8  (0 => OK)
+03 DOUBLE: 1.36512894828617400320e+19 / 0x0043e7ae63eea00000  (0 => OK)
+04 SINGLE: -1.78051176151664730511e-20 / 0x9ea82a22  (0 => OK)
+04 DOUBLE: 1.35347300458215505920e+19 / 0x0043e77aa0a8880000  (0 => OK)
+05 SINGLE: -1.17549435082228750796e-38 / 0x80800000  (0 => OK)
+05 DOUBLE: 1.32631009026061107200e+19 / 0x0043e7020000000000  (0 => OK)
+06 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+06 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+07 SINGLE: 1.17549435082228750796e-38 / 0x00800000  (0 => OK)
+07 DOUBLE: 4.03972886575133491200e+18 / 0x0043cc080000000000  (0 => OK)
+08 SINGLE: 5.96045985901128005934e-08 / 0x337ffff3  (0 => OK)
+08 DOUBLE: 4.49909602076380364800e+18 / 0x0043cf37ffff300000  (0 => OK)
+09 SINGLE: 6.09755988989491015672e-05 / 0x387fc00d  (0 => OK)
+09 DOUBLE: 4.54412323490313011200e+18 / 0x0043cf87fc00d00000  (0 => OK)
+10 SINGLE: 6.10351999057456851005e-05 / 0x38800006  (0 => OK)
+10 DOUBLE: 4.54413202723805593600e+18 / 0x0043cf880000600000  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+11 DOUBLE: 4.60718241880001740800e+18 / 0x0043cff80000000000  (0 => OK)
+12 SINGLE: 1.00097656250000000000e+00 / 0x3f802000  (0 => OK)
+12 DOUBLE: 4.60718681684652851200e+18 / 0x0043cff80200000000  (0 => OK)
+13 SINGLE: 2.00000000000000000000e+00 / 0x40000000  (0 => OK)
+13 DOUBLE: 4.61168601842738790400e+18 / 0x0043d0000000000000  (0 => OK)
+14 SINGLE: 2.71828174591064453125e+00 / 0x402df854  (0 => OK)
+14 DOUBLE: 4.61330344512900300800e+18 / 0x0043d0016fc2a00000  (0 => OK)
+15 SINGLE: 3.14159274101257324218e+00 / 0x40490fdb  (0 => OK)
+15 DOUBLE: 4.61425665674890444800e+18 / 0x0043d002487ed80000  (0 => OK)
+16 SINGLE: 6.55030000000000000000e+04 / 0x477fdf00  (0 => OK)
+16 DOUBLE: 4.67923547735248076800e+18 / 0x0043d03bfef8000000  (0 => OK)
+17 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+17 DOUBLE: 4.67923561479143424000e+18 / 0x0043d03bff00000000  (0 => OK)
+18 SINGLE: 6.55050000000000000000e+04 / 0x477fe100  (0 => OK)
+18 DOUBLE: 4.67923575223038771200e+18 / 0x0043d03bff08000000  (0 => OK)
+19 SINGLE: 1.31007000000000000000e+05 / 0x47ffdf80  (0 => OK)
+19 DOUBLE: 4.68373914569932800000e+18 / 0x0043d03ffefc000000  (0 => OK)
+20 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+20 DOUBLE: 4.68373921441880473600e+18 / 0x0043d03fff00000000  (0 => OK)
+21 SINGLE: 1.31009000000000000000e+05 / 0x47ffe080  (0 => OK)
+21 DOUBLE: 4.68373928313828147200e+18 / 0x0043d03fff04000000  (0 => OK)
+22 SINGLE: 1.11100003258488635272e+30 / 0x71605d5b  (0 => OK)
+22 DOUBLE: 5.05642931230815027200e+18 / 0x0043d18b02ead80000  (0 => OK)
+23 SINGLE: 3.40282346638528859811e+38 / 0x7f7fffff  (0 => OK)
+23 DOUBLE: 5.18364317056656998400e+18 / 0x0043d1fbfffff80000  (0 => OK)
+Converting double-precision to half-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00   HALF: 0xffff  (0x1 =>     INVALID)
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01   HALF: 0xffff  (0x1 =>     INVALID)
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02   HALF: 0xffff  (0x1 =>     INVALID)
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03   HALF: 0xffff  (0x1 =>     INVALID)
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04   HALF: 0xffff  (0x1 =>     INVALID)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08   HALF: 0x8000  (0x18 =>  UNDERFLOW  INEXACT )
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12   HALF: 0x3ff  (0x18 =>  UNDERFLOW  INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13   HALF: 0x400  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14   HALF: 0x3c00  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15   HALF: 0x3c01  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18   HALF: 0000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19   HALF: 0x3c00  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20   HALF: 0x4000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21   HALF: 0x416f  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22   HALF: 0x4248  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23   HALF: 0x7bfe  (0x10 =>    INEXACT )
+Converting double-precision to single-precision
+00 DOUBLE: -1.79769313486231570814e+308 / 0x00ffefffffffffffff  (0 => OK)
+00 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x14 => OVERFLOW   INEXACT )
+01 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+01 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+02 DOUBLE: -3.40282346638528859811e+38 / 0x00c7efffffe0000000  (0 => OK)
+02 SINGLE: 4.28657843200000000000e+09 / 0x4f7f7fff  (0x10 =>    INEXACT )
+03 DOUBLE: -1.11100000000000007529e+31 / 0x00c661874b135ff654  (0 => OK)
+03 SINGLE: 4.07766476800000000000e+09 / 0x4f730c3a  (0x10 =>    INEXACT )
+04 DOUBLE: -1.11099999999999999084e+30 / 0x00c62c0bab523323b9  (0 => OK)
+04 SINGLE: 4.04962432000000000000e+09 / 0x4f71605d  (0x10 =>    INEXACT )
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+05 SINGLE: 3.22122547200000000000e+09 / 0x4f400000  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+06 SINGLE: 3.21283686400000000000e+09 / 0x4f3f8000  (0 => OK)
+07 DOUBLE: -2.22507385850720138309e-308 / 0x008010000000000000  (0 => OK)
+07 SINGLE: 2.14748364800000000000e+09 / 0x4f000000  (0x18 =>  UNDERFLOW  INEXACT )
+08 DOUBLE: -1.17549435082228750796e-38 / 0x00b810000000000000  (0 => OK)
+08 SINGLE: 2.15587225600000000000e+09 / 0x4f008000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10 DOUBLE: 1.17549435082228750796e-38 / 0x003810000000000000  (0 => OK)
+10 SINGLE: 8.38860800000000000000e+06 / 0x4b000000  (0 => OK)
+11 DOUBLE: 5.96046000000000015661e-08 / 0x003e6ffffe6cb2fa82  (0 => OK)
+11 SINGLE: 8.64026560000000000000e+08 / 0x4e4dffff  (0x10 =>    INEXACT )
+12 DOUBLE: 6.09755999999999994298e-05 / 0x003f0ff801a9af58a1  (0 => OK)
+12 SINGLE: 9.47896320000000000000e+08 / 0x4e61ff00  (0x10 =>    INEXACT )
+13 DOUBLE: 6.10352000000000013664e-05 / 0x003f100000c06a1ef5  (0 => OK)
+13 SINGLE: 9.47912704000000000000e+08 / 0x4e620000  (0x10 =>    INEXACT )
+14 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+14 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+15 DOUBLE: 1.00097656250000000000e+00 / 0x003ff0040000000000  (0 => OK)
+15 SINGLE: 1.06536140800000000000e+09 / 0x4e7e0080  (0 => OK)
+16 DOUBLE: 2.22507385850720138309e-308 / 0x000010000000000000  (0 => OK)
+16 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+17 DOUBLE: 1.37899728486072282843e-308 / 0x000009ea82a2287680  (0 => OK)
+17 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+18 DOUBLE: 1.49147387366816238763e-308 / 0x00000ab98fba843210  (0 => OK)
+18 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0x18 =>  UNDERFLOW  INEXACT )
+19 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+19 SINGLE: 1.06535321600000000000e+09 / 0x4e7e0000  (0 => OK)
+20 DOUBLE: 2.00000000000000000000e+00 / 0x004000000000000000  (0 => OK)
+20 SINGLE: 1.07374182400000000000e+09 / 0x4e800000  (0 => OK)
+21 DOUBLE: 2.71828182845904509079e+00 / 0x004005bf0a8b145769  (0 => OK)
+21 SINGLE: 1.07675443200000000000e+09 / 0x4e805bf0  (0x10 =>    INEXACT )
+22 DOUBLE: 3.14159265358979311599e+00 / 0x00400921fb54442d18  (0 => OK)
+22 SINGLE: 1.07852992000000000000e+09 / 0x4e80921f  (0x10 =>    INEXACT )
+23 DOUBLE: 6.55030000000000000000e+04 / 0x0040effbe000000000  (0 => OK)
+23 SINGLE: 1.19956249600000000000e+09 / 0x4e8effbe  (0 => OK)
+Converting half-precision to single-precision
+00   HALF: 0xffff  (0 => OK)
+00 SINGLE: -1.31008000000000000000e+05 / 0xc7ffe000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 SINGLE: -8.18560000000000000000e+04 / 0xc79fe000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 SINGLE: -6.56000000000000000000e+04 / 0xc7802000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 SINGLE: -6.55360000000000000000e+04 / 0xc7800000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 SINGLE: -6.55040000000000000000e+04 / 0xc77fe000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 SINGLE: -2.00000000000000000000e+00 / 0xc0000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 SINGLE: -1.00000000000000000000e+00 / 0xbf800000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 SINGLE: -5.96046447753906250000e-08 / 0xb3800000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 SINGLE: -0.00000000000000000000e+00 / 0x80000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 SINGLE: 0.00000000000000000000e+00 / 0000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 SINGLE: 5.96046447753906250000e-08 / 0x33800000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 SINGLE: 1.00000000000000000000e+00 / 0x3f800000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 SINGLE: 6.55040000000000000000e+04 / 0x477fe000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 SINGLE: 6.55360000000000000000e+04 / 0x47800000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 SINGLE: 6.56000000000000000000e+04 / 0x47802000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 SINGLE: 8.18560000000000000000e+04 / 0x479fe000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 SINGLE: 1.31008000000000000000e+05 / 0x47ffe000  (0 => OK)
+Converting half-precision to double-precision
+00   HALF: 0xffff  (0 => OK)
+00 DOUBLE: -1.31008000000000000000e+05 / 0x00c0fffc0000000000  (0 => OK)
+01   HALF: 0xfcff  (0 => OK)
+01 DOUBLE: -8.18560000000000000000e+04 / 0x00c0f3fc0000000000  (0 => OK)
+02   HALF: 0xfc01  (0 => OK)
+02 DOUBLE: -6.56000000000000000000e+04 / 0x00c0f0040000000000  (0 => OK)
+03   HALF: 0xfc00  (0 => OK)
+03 DOUBLE: -6.55360000000000000000e+04 / 0x00c0f0000000000000  (0 => OK)
+04   HALF: 0xfbff  (0 => OK)
+04 DOUBLE: -6.55040000000000000000e+04 / 0x00c0effc0000000000  (0 => OK)
+05   HALF: 0xc000  (0 => OK)
+05 DOUBLE: -2.00000000000000000000e+00 / 0x00c000000000000000  (0 => OK)
+06   HALF: 0xbc00  (0 => OK)
+06 DOUBLE: -1.00000000000000000000e+00 / 0x00bff0000000000000  (0 => OK)
+07   HALF: 0x8001  (0 => OK)
+07 DOUBLE: -5.96046447753906250000e-08 / 0x00be70000000000000  (0 => OK)
+08   HALF: 0x8000  (0 => OK)
+08 DOUBLE: -0.00000000000000000000e+00 / 0x008000000000000000  (0 => OK)
+09   HALF: 0000  (0 => OK)
+09 DOUBLE: 0.00000000000000000000e+00 / 00000000000000000000  (0 => OK)
+10   HALF: 0x01  (0 => OK)
+10 DOUBLE: 5.96046447753906250000e-08 / 0x003e70000000000000  (0 => OK)
+11   HALF: 0x3c00  (0 => OK)
+11 DOUBLE: 1.00000000000000000000e+00 / 0x003ff0000000000000  (0 => OK)
+12   HALF: 0x7bff  (0 => OK)
+12 DOUBLE: 6.55040000000000000000e+04 / 0x0040effc0000000000  (0 => OK)
+13   HALF: 0x7c00  (0 => OK)
+13 DOUBLE: 6.55360000000000000000e+04 / 0x0040f0000000000000  (0 => OK)
+14   HALF: 0x7c01  (0 => OK)
+14 DOUBLE: 6.56000000000000000000e+04 / 0x0040f0040000000000  (0 => OK)
+15   HALF: 0x7cff  (0 => OK)
+15 DOUBLE: 8.18560000000000000000e+04 / 0x0040f3fc0000000000  (0 => OK)
+16   HALF: 0x7fff  (0 => OK)
+16 DOUBLE: 1.31008000000000000000e+05 / 0x0040fffc0000000000  (0 => OK)
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP
  2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
                   ` (2 preceding siblings ...)
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 3/3] tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM) Alex Bennée
@ 2018-05-02 15:54 ` no-reply
  2018-05-02 16:28 ` Richard Henderson
  4 siblings, 0 replies; 12+ messages in thread
From: no-reply @ 2018-05-02 15:54 UTC (permalink / raw)
  To: alex.bennee; +Cc: famz, peter.maydell, qemu-arm, richard.henderson, qemu-devel

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180502154344.10585-1-alex.bennee@linaro.org
Subject: [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 t [tag update]            patchew/20180502140359.18222-1-mreitz@redhat.com -> patchew/20180502140359.18222-1-mreitz@redhat.com
 * [new tag]               patchew/20180502154344.10585-1-alex.bennee@linaro.org -> patchew/20180502154344.10585-1-alex.bennee@linaro.org
Switched to a new branch 'test'
df8db34ba1 tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM)
c2fe988262 fpu/softfloat: support ARM Alternative half-precision
ec8c70c013 fpu/softfloat: re-factor float to float conversions

=== OUTPUT BEGIN ===
Checking PATCH 1/3: fpu/softfloat: re-factor float to float conversions...
Checking PATCH 2/3: fpu/softfloat: support ARM Alternative half-precision...
Checking PATCH 3/3: tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM)...
ERROR: spaces required around that '+' (ctx:VxV)
#85: FILE: tests/tcg/aarch64/fcvt.c:61:
+                           -1.111E+31,
                                   ^

ERROR: spaces required around that '+' (ctx:VxV)
#86: FILE: tests/tcg/aarch64/fcvt.c:62:
+                           -1.111E+30,
                                   ^

ERROR: spaces required around that '-' (ctx:VxV)
#87: FILE: tests/tcg/aarch64/fcvt.c:63:
+                           -1.08700982e-12,
                                        ^

ERROR: spaces required around that '-' (ctx:VxV)
#88: FILE: tests/tcg/aarch64/fcvt.c:64:
+                           -1.78051176e-20,
                                        ^

ERROR: spaces required around that '-' (ctx:VxV)
#92: FILE: tests/tcg/aarch64/fcvt.c:68:
+                           5.96046E-8, /* min positive FP16 subnormal */
                                    ^

ERROR: spaces required around that '-' (ctx:VxV)
#93: FILE: tests/tcg/aarch64/fcvt.c:69:
+                           6.09756E-5, /* max subnormal FP16 */
                                    ^

ERROR: spaces required around that '-' (ctx:VxV)
#94: FILE: tests/tcg/aarch64/fcvt.c:70:
+                           6.10352E-5, /* min positive normal FP16 */
                                    ^

ERROR: spaces required around that '+' (ctx:VxV)
#105: FILE: tests/tcg/aarch64/fcvt.c:81:
+                           1.111E+30,
                                  ^

ERROR: spaces required around that '-' (ctx:VxV)
#145: FILE: tests/tcg/aarch64/fcvt.c:121:
+                            -FLT_MAX-1.0,
                                     ^

ERROR: spaces required around that '+' (ctx:VxV)
#147: FILE: tests/tcg/aarch64/fcvt.c:123:
+                            -1.111E+31,
                                    ^

ERROR: spaces required around that '+' (ctx:VxV)
#148: FILE: tests/tcg/aarch64/fcvt.c:124:
+                            -1.111E+30, /* half prec */
                                    ^

ERROR: spaces required around that '-' (ctx:VxV)
#154: FILE: tests/tcg/aarch64/fcvt.c:130:
+                            5.96046E-8, /* min positive FP16 subnormal */
                                     ^

ERROR: spaces required around that '-' (ctx:VxV)
#155: FILE: tests/tcg/aarch64/fcvt.c:131:
+                            6.09756E-5, /* max subnormal FP16 */
                                     ^

ERROR: spaces required around that '-' (ctx:VxV)
#156: FILE: tests/tcg/aarch64/fcvt.c:132:
+                            6.10352E-5, /* min positive normal FP16 */
                                     ^

ERROR: spaces required around that '-' (ctx:VxV)
#160: FILE: tests/tcg/aarch64/fcvt.c:136:
+                            1.3789972848607228e-308,
                                                ^

ERROR: spaces required around that '-' (ctx:VxV)
#161: FILE: tests/tcg/aarch64/fcvt.c:137:
+                            1.4914738736681624e-308,
                                                ^

ERROR: space prohibited before open square bracket '['
#304: FILE: tests/tcg/aarch64/fcvt.c:280:
+        : /* no output */ : [flags] "n" (1 << 26) : "x1" );

ERROR: space prohibited before that close parenthesis ')'
#304: FILE: tests/tcg/aarch64/fcvt.c:280:
+        : /* no output */ : [flags] "n" (1 << 26) : "x1" );

total: 18 errors, 0 warnings, 2434 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions Alex Bennée
@ 2018-05-02 16:26   ` Richard Henderson
  0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2018-05-02 16:26 UTC (permalink / raw)
  To: Alex Bennée, peter.maydell; +Cc: qemu-arm, qemu-devel, Aurelien Jarno

On 05/02/2018 08:43 AM, Alex Bennée wrote:
> +    if (is_nan(a.cls)) {
> +
> +        if (is_snan(a.cls)) {

Watch your whitespace.


r~

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP
  2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
                   ` (3 preceding siblings ...)
  2018-05-02 15:54 ` [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP no-reply
@ 2018-05-02 16:28 ` Richard Henderson
  4 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2018-05-02 16:28 UTC (permalink / raw)
  To: Alex Bennée, peter.maydell; +Cc: qemu-arm, qemu-devel

On 05/02/2018 08:43 AM, Alex Bennée wrote:
> This is a more polished version of the re-factoring of the softfloat
> fcvt code. I've split apart the fixes for ARM alternative
> half-precision format for easier review. Rather than rely on some
> questionable hacks it introduces a new FloatFmt to allow cleaner
> handling of the differences in the common code. If there are other
> alternative floating point formats they can follow a similar approach.
> 
> I've included the test case for reference although I expect it to be
> merged with my tcg-testing revival code which has the rest of the
> build and test machinery for the test case.
> 
> checkpatch dumps a bunch of false-positives as it doesn't like
> scientific notation for floats or inline assembler used in the test
> case.
> 
> Cheers,
> 
> Alex Bennée (3):
>   fpu/softfloat: re-factor float to float conversions
>   fpu/softfloat: support ARM Alternative half-precision
>   tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision Alex Bennée
@ 2018-05-03 18:17   ` Peter Maydell
  2018-05-03 19:41     ` Alex Bennée
  2018-05-03 20:09     ` Richard Henderson
  0 siblings, 2 replies; 12+ messages in thread
From: Peter Maydell @ 2018-05-03 18:17 UTC (permalink / raw)
  To: Alex Bennée
  Cc: Richard Henderson, qemu-arm, QEMU Developers, Aurelien Jarno

On 2 May 2018 at 16:43, Alex Bennée <alex.bennee@linaro.org> wrote:
> For float16 ARM supports an alternative half-precision format which
> sacrifices the ability to represent NaN/Inf in return for a higher
> dynamic range. To support this I've added an additional
> FloatFmt (float16_params_ahp).
>
> The new FloatFmt flag (arm_althp) is then used to modify the behaviour
> of canonicalize and round_canonical with respect to representation and
> exception raising.
>
> Finally the float16_to_floatN and floatN_to_float16 conversion
> routines select the new alternative FloatFmt when !ieee.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  fpu/softfloat.c | 97 +++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 74 insertions(+), 23 deletions(-)

I found some corner cases where this patchset introduces
regressions; details below... They're not all althp related
but I started composing this email in reply to patch 2/3 and
don't want to try to move it to replying to the cover letter now :-)


(1) Here's an example of a wrong 32->16 conversion in alt-hp mode:
for FCVT h5, s0 where s0 is an SNaN, then your code gives 0x7E00
when it should give 0x0, because float16a_round_pack_canonical()
tries to return a NaN, which doesn't exist in alt-HP.

In the Arm ARM pseudocode this case is handled by the
FPConvert pseudocode, which treats alt_hp specially
when the input is a NaN. On that analogy I put this into
float_to_float(), which seems to have the desired effect:

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 25a331158f..1cc368175d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1256,6 +1256,17 @@ static FloatParts float_to_float(FloatParts a,
             s->float_exception_flags |= float_flag_invalid;
         }

+        if (dstf->arm_althp) {
+            /* There is no NaN in the destination format: raise Invalid
+             * and return a zero with the sign of the input NaN.
+             */
+            s->float_exception_flags |= float_flag_invalid;
+            a.cls = float_class_zero;
+            a.frac = 0;
+            a.exp = 0;
+            return a;
+        }
+
         if (s->default_nan_mode) {
             a.cls = float_class_dnan;
             return a;

(2) You're also failing to set the Inexact flag for cases like
 fcvt h1, s0     where s0 is 0x33000000
which should return result of 0, flags Inexact | Underflow,
but is after this patchset returning just Underflow.

I think this is because you're not dealing with the
odd handling of flush-to-zero for half-precision:
in the v8A Arm ARM pseudocode, float-to-float conversion
uses the FPRoundCV() function, which squashes FZ16 to 0,
and FPRoundBase() looks at fpcr.FZ for 32 and 64 bit floats
but fpcr.FZ16 for 16 bit floats. (FZ16 exists only with the
halfprec extension, and effectively applies only for the
data processing and int<->fp conversions -- see FPRound().)

In our old code we handled this implicitly by having
roundAndPackFloat16() not check status->flush_to_zero the way
that roundAndPackFloat32/64 did. Now you've combined them all
into one code path you need to do some special casing, I think.
This change fixes things for the fcvt case, but (a) is a
dubious hack and (b) you'll want to do something different
to handle FZ16 for actual arithmetic operations on halfprec.
If architectures other than Arm use halfprec (MIPS seems to)
then we should check what their semantics are to see if they
match Arm.

--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -453,7 +453,7 @@ static FloatParts round_canonical(FloatParts p,
float_status *s,
                     flags |= float_flag_inexact;
                 }
             }
-        } else if (s->flush_to_zero) {
+        } else if (s->flush_to_zero && parm->exp_size != 5) {
             flags |= float_flag_output_denormal;
             p.cls = float_class_zero;
             goto do_zero;

(3) Here's a NaN case we get wrong now: 64 to IEEE-16 conversion,
input is 0x7ff0000000000001 (an SNaN), we produce
0x7c00 (infinity) but should produce 0x7e00 (a QNaN).

This is because this code in float16a_round_pack_canonical():

    case float_class_msnan:
        return float16_maybe_silence_nan(float16_pack_raw(p), s);

doesn't consider the possibility that float16_pack_raw()
ends up with something that's not a NaN. In this case
because the float-to-float conversion has thrown away the
bottom bits of the double's mantissa, we have p.frac == 0,
and float16_pack_raw() gives 0x7c00, which is an infinity,
not a NaN. So when float16_maybe_silence_nan() calls
float16_is_signaling_nan() on it it returns false and then
we don't change the SNaN bit.

The code as of this patch seems to be a bit confused:
it does part of the conversion of NaNs from one format
to the other in float_to_float() (which is where it's
fiddling with the frac bits) and part of it in
the round_canonical() case (where it then messes
about with quietening the NaN). In an ideal world
this would all be punted out to the softfloat-specialize
code to convert with access to the full details of the
input number, because it's impdef how NaN conversion handles
the fraction bits. Arm happens to choose to use the
most significant bits of the fraction field, but there's
no theoretical reason why you couldn't have an
implementation that wanted to preserve the least
significant bits, for instance.

Note also that we currently have workarounds at the target/arm
level for the softfloat code not quietening input NaNs for
fp-to-fp conversion: see the uses of float*_maybe_silence_nan()
after float*_to_float* calls in target/arm/helper.c.
If the softfloat code is now going to get these correct then
we can drop those. HPPA, MIPS, RISCV and S390x have similar
workarounds also. Overall, the maybe_silence_nan function
was a dubious workaround for not having been able to do
the NaN handling when we had a fully unpacked value, and
perhaps we can minimise its use or even get rid of it...
(target/i386 notably does not do this, we should check how
SSE and x87 handle NaNs in fp conversions first.)

thanks
-- PMM

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-03 18:17   ` Peter Maydell
@ 2018-05-03 19:41     ` Alex Bennée
  2018-05-03 20:09     ` Richard Henderson
  1 sibling, 0 replies; 12+ messages in thread
From: Alex Bennée @ 2018-05-03 19:41 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Richard Henderson, qemu-arm, QEMU Developers, Aurelien Jarno


Peter Maydell <peter.maydell@linaro.org> writes:

> On 2 May 2018 at 16:43, Alex Bennée <alex.bennee@linaro.org> wrote:
>> For float16 ARM supports an alternative half-precision format which
>> sacrifices the ability to represent NaN/Inf in return for a higher
>> dynamic range. To support this I've added an additional
>> FloatFmt (float16_params_ahp).
>>
>> The new FloatFmt flag (arm_althp) is then used to modify the behaviour
>> of canonicalize and round_canonical with respect to representation and
>> exception raising.
>>
>> Finally the float16_to_floatN and floatN_to_float16 conversion
>> routines select the new alternative FloatFmt when !ieee.
>>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>> ---
>>  fpu/softfloat.c | 97 +++++++++++++++++++++++++++++++++++++------------
>>  1 file changed, 74 insertions(+), 23 deletions(-)
>
> I found some corner cases where this patchset introduces
> regressions; details below... They're not all althp related
> but I started composing this email in reply to patch 2/3 and
> don't want to try to move it to replying to the cover letter now :-)
>
>
> (1) Here's an example of a wrong 32->16 conversion in alt-hp mode:
> for FCVT h5, s0 where s0 is an SNaN, then your code gives 0x7E00
> when it should give 0x0, because float16a_round_pack_canonical()
> tries to return a NaN, which doesn't exist in alt-HP.
>
> In the Arm ARM pseudocode this case is handled by the
> FPConvert pseudocode, which treats alt_hp specially
> when the input is a NaN. On that analogy I put this into
> float_to_float(), which seems to have the desired effect:
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 25a331158f..1cc368175d 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -1256,6 +1256,17 @@ static FloatParts float_to_float(FloatParts a,
>              s->float_exception_flags |= float_flag_invalid;
>          }
>
> +        if (dstf->arm_althp) {
> +            /* There is no NaN in the destination format: raise Invalid
> +             * and return a zero with the sign of the input NaN.
> +             */
> +            s->float_exception_flags |= float_flag_invalid;
> +            a.cls = float_class_zero;
> +            a.frac = 0;
> +            a.exp = 0;
> +            return a;
> +        }
> +

Doh. The previous version had handling for this in float_to_float but it
was clear on my test case and I thought I'd handled it all in the
unpack/canonicalize step.

>          if (s->default_nan_mode) {
>              a.cls = float_class_dnan;
>              return a;
>
> (2) You're also failing to set the Inexact flag for cases like
>  fcvt h1, s0     where s0 is 0x33000000
> which should return result of 0, flags Inexact | Underflow,
> but is after this patchset returning just Underflow.

More cases for the test case ;-)

>
> I think this is because you're not dealing with the
> odd handling of flush-to-zero for half-precision:
> in the v8A Arm ARM pseudocode, float-to-float conversion
> uses the FPRoundCV() function, which squashes FZ16 to 0,
> and FPRoundBase() looks at fpcr.FZ for 32 and 64 bit floats
> but fpcr.FZ16 for 16 bit floats. (FZ16 exists only with the
> halfprec extension, and effectively applies only for the
> data processing and int<->fp conversions -- see FPRound().)
>
> In our old code we handled this implicitly by having
> roundAndPackFloat16() not check status->flush_to_zero the way
> that roundAndPackFloat32/64 did. Now you've combined them all
> into one code path you need to do some special casing, I think.
> This change fixes things for the fcvt case, but (a) is a
> dubious hack and (b) you'll want to do something different
> to handle FZ16 for actual arithmetic operations on halfprec.

We handle FZ16 by passing a different float_status for halfprec. But I
guess the fcvt helpers can do the save/squash/restore dance.

> If architectures other than Arm use halfprec (MIPS seems to)
> then we should check what their semantics are to see if they
> match Arm.

There are helpers but I couldn't see them actually being called. I was
half tempted to delete the helpers and rationalise the softfloat API
convention but decided against it to avoid churn.

>
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -453,7 +453,7 @@ static FloatParts round_canonical(FloatParts p,
> float_status *s,
>                      flags |= float_flag_inexact;
>                  }
>              }
> -        } else if (s->flush_to_zero) {
> +        } else if (s->flush_to_zero && parm->exp_size != 5) {
>              flags |= float_flag_output_denormal;
>              p.cls = float_class_zero;
>              goto do_zero;
>
> (3) Here's a NaN case we get wrong now: 64 to IEEE-16 conversion,
> input is 0x7ff0000000000001 (an SNaN), we produce
> 0x7c00 (infinity) but should produce 0x7e00 (a QNaN).

OK.

>
> This is because this code in float16a_round_pack_canonical():
>
>     case float_class_msnan:
>         return float16_maybe_silence_nan(float16_pack_raw(p), s);
>
> doesn't consider the possibility that float16_pack_raw()
> ends up with something that's not a NaN. In this case
> because the float-to-float conversion has thrown away the
> bottom bits of the double's mantissa, we have p.frac == 0,
> and float16_pack_raw() gives 0x7c00, which is an infinity,
> not a NaN. So when float16_maybe_silence_nan() calls
> float16_is_signaling_nan() on it it returns false and then
> we don't change the SNaN bit.
>
> The code as of this patch seems to be a bit confused:
> it does part of the conversion of NaNs from one format
> to the other in float_to_float() (which is where it's
> fiddling with the frac bits) and part of it in
> the round_canonical() case (where it then messes
> about with quietening the NaN). In an ideal world
> this would all be punted out to the softfloat-specialize
> code to convert with access to the full details of the
> input number, because it's impdef how NaN conversion handles
> the fraction bits. Arm happens to choose to use the
> most significant bits of the fraction field, but there's
> no theoretical reason why you couldn't have an
> implementation that wanted to preserve the least
> significant bits, for instance.
>
> Note also that we currently have workarounds at the target/arm
> level for the softfloat code not quietening input NaNs for
> fp-to-fp conversion: see the uses of float*_maybe_silence_nan()
> after float*_to_float* calls in target/arm/helper.c.
> If the softfloat code is now going to get these correct then
> we can drop those. HPPA, MIPS, RISCV and S390x have similar
> workarounds also. Overall, the maybe_silence_nan function
> was a dubious workaround for not having been able to do
> the NaN handling when we had a fully unpacked value, and
> perhaps we can minimise its use or even get rid of it...
> (target/i386 notably does not do this, we should check how
> SSE and x87 handle NaNs in fp conversions first.)

I guess it is time to expose some of the details for the unpacked float
handling to specialize so its not an after the fact hack.

>
> thanks
> -- PMM


--
Alex Bennée

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-03 18:17   ` Peter Maydell
  2018-05-03 19:41     ` Alex Bennée
@ 2018-05-03 20:09     ` Richard Henderson
  2018-05-04 12:26       ` Alex Bennée
  1 sibling, 1 reply; 12+ messages in thread
From: Richard Henderson @ 2018-05-03 20:09 UTC (permalink / raw)
  To: Peter Maydell, Alex Bennée; +Cc: qemu-arm, QEMU Developers, Aurelien Jarno

On 05/03/2018 11:17 AM, Peter Maydell wrote:
> (target/i386 notably does not do this, we should check how
> SSE and x87 handle NaNs in fp conversions first.)

Hardware does silence NaNs.  I tested that earlier:

https://lists.gnu.org/archive/html/qemu-devel/2018-04/msg03114.html


r~

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-03 20:09     ` Richard Henderson
@ 2018-05-04 12:26       ` Alex Bennée
  2018-05-04 15:36         ` Richard Henderson
  0 siblings, 1 reply; 12+ messages in thread
From: Alex Bennée @ 2018-05-04 12:26 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, qemu-arm, QEMU Developers, Aurelien Jarno


Richard Henderson <richard.henderson@linaro.org> writes:

> On 05/03/2018 11:17 AM, Peter Maydell wrote:
>> (target/i386 notably does not do this, we should check how
>> SSE and x87 handle NaNs in fp conversions first.)
>
> Hardware does silence NaNs.  I tested that earlier:
>
> https://lists.gnu.org/archive/html/qemu-devel/2018-04/msg03114.html

Does that include SSE? I know the hardware will silence NaN's if the
value is ever pushed into an x87 register (as GCC will do when
spilling/filling float).

>
>
> r~


--
Alex Bennée

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision
  2018-05-04 12:26       ` Alex Bennée
@ 2018-05-04 15:36         ` Richard Henderson
  0 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2018-05-04 15:36 UTC (permalink / raw)
  To: Alex Bennée; +Cc: Peter Maydell, qemu-arm, QEMU Developers, Aurelien Jarno

On 05/04/2018 05:26 AM, Alex Bennée wrote:
> 
> Richard Henderson <richard.henderson@linaro.org> writes:
> 
>> On 05/03/2018 11:17 AM, Peter Maydell wrote:
>>> (target/i386 notably does not do this, we should check how
>>> SSE and x87 handle NaNs in fp conversions first.)
>>
>> Hardware does silence NaNs.  I tested that earlier:
>>
>> https://lists.gnu.org/archive/html/qemu-devel/2018-04/msg03114.html
> 
> Does that include SSE?

Yes.

> I know the hardware will silence NaN's if the
> value is ever pushed into an x87 register (as GCC will do when
> spilling/filling float).

Actually, loads and stores are purely bit operations that do not modify data.


r~

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-05-04 15:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-02 15:43 [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP Alex Bennée
2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 1/3] fpu/softfloat: re-factor float to float conversions Alex Bennée
2018-05-02 16:26   ` Richard Henderson
2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 2/3] fpu/softfloat: support ARM Alternative half-precision Alex Bennée
2018-05-03 18:17   ` Peter Maydell
2018-05-03 19:41     ` Alex Bennée
2018-05-03 20:09     ` Richard Henderson
2018-05-04 12:26       ` Alex Bennée
2018-05-04 15:36         ` Richard Henderson
2018-05-02 15:43 ` [Qemu-devel] [PATCH v2 3/3] tests/tcg/aarch64: add fcvt test cases for AArch64 (!UPSTREAM) Alex Bennée
2018-05-02 15:54 ` [Qemu-devel] [PATCH v2 0/3] refactor float-to-float conversions and fix AHP no-reply
2018-05-02 16:28 ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.