* IBM extended precision 128-bit floating-point format, aka IBM double-double * * IBM's double-double type is a pair of IEEE binary64 values, which you add * together to get a total value. The exponents are arranged so that the lower * double is about 2^52 times smaller than the high one, and the nearest * float64 value is simply the upper double, in which case the pair is * considered "norm
| 2876 | * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/128bit_long_double_floating-point_datatype.htm |
| 2877 | */ |
| 2878 | static npy_uint32 |
| 2879 | Dragon4_PrintFloat_IBM_double_double( |
| 2880 | Dragon4_Scratch *scratch, npy_float128 *value, Dragon4_Options *opt) |
| 2881 | { |
| 2882 | char *buffer = scratch->repr; |
| 2883 | const npy_uint32 bufferSize = sizeof(scratch->repr); |
| 2884 | BigInt *bigints = scratch->bigints; |
| 2885 | |
| 2886 | FloatVal128 val128; |
| 2887 | FloatUnion128 buf128; |
| 2888 | |
| 2889 | npy_uint32 floatExponent1, floatExponent2; |
| 2890 | npy_uint64 floatMantissa1, floatMantissa2; |
| 2891 | npy_uint32 floatSign1, floatSign2; |
| 2892 | |
| 2893 | npy_uint64 mantissa1, mantissa2; |
| 2894 | npy_int32 exponent1, exponent2; |
| 2895 | int shift; |
| 2896 | npy_uint32 mantissaBit; |
| 2897 | npy_bool hasUnequalMargins; |
| 2898 | char signbit = '\0'; |
| 2899 | |
| 2900 | /* The high part always comes before the low part, regardless of the |
| 2901 | * endianness of the system. */ |
| 2902 | buf128.floatingPoint = *value; |
| 2903 | val128.hi = buf128.integer.a; |
| 2904 | val128.lo = buf128.integer.b; |
| 2905 | |
| 2906 | /* deconstruct the floating point values */ |
| 2907 | floatMantissa1 = val128.hi & bitmask_u64(52); |
| 2908 | floatExponent1 = (val128.hi >> 52) & bitmask_u32(11); |
| 2909 | floatSign1 = (val128.hi >> 63) != 0; |
| 2910 | |
| 2911 | floatMantissa2 = val128.lo & bitmask_u64(52); |
| 2912 | floatExponent2 = (val128.lo >> 52) & bitmask_u32(11); |
| 2913 | floatSign2 = (val128.lo >> 63) != 0; |
| 2914 | |
| 2915 | /* output the sign using 1st float's sign */ |
| 2916 | if (floatSign1) { |
| 2917 | signbit = '-'; |
| 2918 | } |
| 2919 | else if (opt->sign) { |
| 2920 | signbit = '+'; |
| 2921 | } |
| 2922 | |
| 2923 | /* we only need to look at the first float for inf/nan */ |
| 2924 | if (floatExponent1 == bitmask_u32(11)) { |
| 2925 | return PrintInfNan(buffer, bufferSize, floatMantissa1, 13, signbit); |
| 2926 | } |
| 2927 | |
| 2928 | /* else this is a number */ |
| 2929 | |
| 2930 | /* Factor the 1st value into its parts, see binary64 for comments. */ |
| 2931 | if (floatExponent1 == 0) { |
| 2932 | /* |
| 2933 | * If the first number is a subnormal value, the 2nd has to be 0 for |
| 2934 | * the float128 to be normalized, so we can ignore it. In this case |
| 2935 | * the float128 only has the precision of a single binary64 value. |
nothing calls this directly
no test coverage detected