* Intel's 80-bit IEEE extended precision floating-point format * * "long doubles" with this format are stored as 96 or 128 bits, but * are equivalent to the 80 bit type with some zero padding on the high bits. * This method expects the user to pass in the value using a 128-bit * FloatVal128, so can support 80, 96, or 128 bit storage formats, * and is endian-independent. * * sign: 1 bi
| 2504 | * mantissa: 63 bits, first u64 |
| 2505 | */ |
| 2506 | static npy_uint32 |
| 2507 | Dragon4_PrintFloat_Intel_extended( |
| 2508 | Dragon4_Scratch *scratch, FloatVal128 value, Dragon4_Options *opt) |
| 2509 | { |
| 2510 | char *buffer = scratch->repr; |
| 2511 | const npy_uint32 bufferSize = sizeof(scratch->repr); |
| 2512 | BigInt *bigints = scratch->bigints; |
| 2513 | |
| 2514 | npy_uint32 floatExponent, floatSign; |
| 2515 | npy_uint64 floatMantissa; |
| 2516 | |
| 2517 | npy_uint64 mantissa; |
| 2518 | npy_int32 exponent; |
| 2519 | npy_uint32 mantissaBit; |
| 2520 | npy_bool hasUnequalMargins; |
| 2521 | char signbit = '\0'; |
| 2522 | |
| 2523 | /* deconstruct the floating point value (we ignore the intbit) */ |
| 2524 | floatMantissa = value.lo & bitmask_u64(63); |
| 2525 | floatExponent = value.hi & bitmask_u32(15); |
| 2526 | floatSign = (value.hi >> 15) & 0x1; |
| 2527 | |
| 2528 | /* output the sign */ |
| 2529 | if (floatSign != 0) { |
| 2530 | signbit = '-'; |
| 2531 | } |
| 2532 | else if (opt->sign) { |
| 2533 | signbit = '+'; |
| 2534 | } |
| 2535 | |
| 2536 | /* if this is a special value */ |
| 2537 | if (floatExponent == bitmask_u32(15)) { |
| 2538 | /* |
| 2539 | * Note: Technically there are other special extended values defined if |
| 2540 | * the intbit is 0, like Pseudo-Infinity, Pseudo-Nan, Quiet-NaN. We |
| 2541 | * ignore all of these since they are not generated on modern |
| 2542 | * processors. We treat Quiet-Nan as simply Nan. |
| 2543 | */ |
| 2544 | return PrintInfNan(buffer, bufferSize, floatMantissa, 16, signbit); |
| 2545 | } |
| 2546 | /* else this is a number */ |
| 2547 | |
| 2548 | /* factor the value into its parts */ |
| 2549 | if (floatExponent != 0) { |
| 2550 | /* |
| 2551 | * normal |
| 2552 | * The floating point equation is: |
| 2553 | * value = (1 + mantissa/2^63) * 2 ^ (exponent-16383) |
| 2554 | * We convert the integer equation by factoring a 2^63 out of the |
| 2555 | * exponent |
| 2556 | * value = (1 + mantissa/2^63) * 2^63 * 2 ^ (exponent-16383-63) |
| 2557 | * value = (2^63 + mantissa) * 2 ^ (exponent-16383-63) |
| 2558 | * Because of the implied 1 in front of the mantissa we have 64 bits of |
| 2559 | * precision. |
| 2560 | * m = (2^63 + mantissa) |
| 2561 | * e = (exponent-16383+1-64) |
| 2562 | */ |
| 2563 | mantissa = (1ull << 63) | floatMantissa; |
no test coverage detected