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

Function Dragon4_PrintFloat_IBM_double_double

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

* 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

Source from the content-addressed store, hash-verified

2876 * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/128bit_long_double_floating-point_datatype.htm
2877 */
2878static npy_uint32
2879Dragon4_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.

Callers

nothing calls this directly

Calls 7

bitmask_u64Function · 0.85
bitmask_u32Function · 0.85
PrintInfNanFunction · 0.85
LogBase2_64Function · 0.85
BigInt_Set_uint64Function · 0.85
BigInt_Set_2x_uint64Function · 0.85
Format_floatbitsFunction · 0.85

Tested by

no test coverage detected