MCPcopy Create free account
hub / github.com/numpy/numpy / Dragon4_PrintFloat_IEEE_binary128

Function Dragon4_PrintFloat_IEEE_binary128

numpy/core/src/multiarray/dragon4.c:2718–2800  ·  view source on GitHub ↗

* IEEE binary128 floating-point format * * sign: 1 bit * exponent: 15 bits * mantissa: 112 bits * * Currently binary128 format exists on only a few CPUs, such as on the POWER9 * arch or aarch64. Because of this, this code has not been extensively tested. * I am not sure if the arch also supports uint128, and C does not seem to * support int128 literals. So we use uint64 to do manip

Source from the content-addressed store, hash-verified

2716 * support int128 literals. So we use uint64 to do manipulation.
2717 */
2718static npy_uint32
2719Dragon4_PrintFloat_IEEE_binary128(
2720 Dragon4_Scratch *scratch, FloatVal128 val128, Dragon4_Options *opt)
2721{
2722 char *buffer = scratch->repr;
2723 const npy_uint32 bufferSize = sizeof(scratch->repr);
2724 BigInt *bigints = scratch->bigints;
2725
2726 npy_uint32 floatExponent, floatSign;
2727
2728 npy_uint64 mantissa_hi, mantissa_lo;
2729 npy_int32 exponent;
2730 npy_uint32 mantissaBit;
2731 npy_bool hasUnequalMargins;
2732 char signbit = '\0';
2733
2734 mantissa_hi = val128.hi & bitmask_u64(48);
2735 mantissa_lo = val128.lo;
2736 floatExponent = (val128.hi >> 48) & bitmask_u32(15);
2737 floatSign = val128.hi >> 63;
2738
2739 /* output the sign */
2740 if (floatSign != 0) {
2741 signbit = '-';
2742 }
2743 else if (opt->sign) {
2744 signbit = '+';
2745 }
2746
2747 /* if this is a special value */
2748 if (floatExponent == bitmask_u32(15)) {
2749 npy_uint64 mantissa_zero = mantissa_hi == 0 && mantissa_lo == 0;
2750 return PrintInfNan(buffer, bufferSize, !mantissa_zero, 16, signbit);
2751 }
2752 /* else this is a number */
2753
2754 /* factor the value into its parts */
2755 if (floatExponent != 0) {
2756 /*
2757 * normal
2758 * The floating point equation is:
2759 * value = (1 + mantissa/2^112) * 2 ^ (exponent-16383)
2760 * We convert the integer equation by factoring a 2^112 out of the
2761 * exponent
2762 * value = (1 + mantissa/2^112) * 2^112 * 2 ^ (exponent-16383-112)
2763 * value = (2^112 + mantissa) * 2 ^ (exponent-16383-112)
2764 * Because of the implied 1 in front of the mantissa we have 112 bits of
2765 * precision.
2766 * m = (2^112 + mantissa)
2767 * e = (exponent-16383+1-112)
2768 *
2769 * Adding 2^112 to the mantissa is the same as adding 2^48 to the hi
2770 * 64 bit part.
2771 */
2772 mantissa_hi = (1ull << 48) | mantissa_hi;
2773 /* mantissa_lo is unchanged */
2774 exponent = floatExponent - 16383 - 112;
2775 mantissaBit = 112;

Calls 6

bitmask_u64Function · 0.85
bitmask_u32Function · 0.85
PrintInfNanFunction · 0.85
LogBase2_128Function · 0.85
BigInt_Set_2x_uint64Function · 0.85
Format_floatbitsFunction · 0.85

Tested by

no test coverage detected