* 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
| 2716 | * support int128 literals. So we use uint64 to do manipulation. |
| 2717 | */ |
| 2718 | static npy_uint32 |
| 2719 | Dragon4_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; |
no test coverage detected