1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <libpspp/float-format.h>
28 #include <libpspp/assertion.h>
29 #include <libpspp/integer-format.h>
30 #include <libpspp/str.h>
35 /* Neutral intermediate representation for binary floating-point numbers. */
40 FINITE, /* Finite number (normalized or denormalized). */
41 INFINITE, /* Positive or negative infinity. */
42 NAN, /* Not a number. */
44 ZERO, /* Positive or negative zero. */
45 MISSING, /* System missing. */
46 LOWEST, /* LOWEST on e.g. missing values. */
47 HIGHEST, /* HIGHEST on e.g. missing values. */
48 RESERVED /* Special Vax representation. */
59 /* class == FINITE: The number has value "fraction *
60 2**exponent", considering bit 63 in fraction to be just
61 right of the decimal point.
63 class == NAN: The fraction holds the significand, with its
64 leftmost bit in bit 63, so that signaling and quiet NaN
65 values can be preserved.
67 Unused for other classes. */
72 static void extract_number (enum float_format, const void *, struct fp *);
73 static void assemble_number (enum float_format, struct fp *, void *);
75 static inline uint16_t get_uint16 (const void *);
76 static inline uint32_t get_uint32 (const void *);
77 static inline uint64_t get_uint64 (const void *);
79 static inline void put_uint16 (uint16_t, void *);
80 static inline void put_uint32 (uint32_t, void *);
81 static inline void put_uint64 (uint64_t, void *);
83 /* Converts SRC from format FROM to format TO, storing the
84 converted value into DST.
85 SRC and DST are permitted to arbitrarily overlap. */
87 float_convert (enum float_format from, const void *src,
88 enum float_format to, void *dst)
92 if ((from == FLOAT_IEEE_SINGLE_LE || from == FLOAT_IEEE_SINGLE_BE)
93 && (to == FLOAT_IEEE_SINGLE_LE || to == FLOAT_IEEE_SINGLE_BE))
94 put_uint32 (bswap_32 (get_uint32 (src)), dst);
95 else if ((from == FLOAT_IEEE_DOUBLE_LE || from == FLOAT_IEEE_DOUBLE_BE)
96 && (to == FLOAT_IEEE_DOUBLE_LE || to == FLOAT_IEEE_DOUBLE_BE))
97 put_uint64 (bswap_64 (get_uint64 (src)), dst);
101 extract_number (from, src, &fp);
102 assemble_number (to, &fp, dst);
108 memmove (dst, src, float_get_size (from));
112 /* Returns the number of bytes in a number in the given
115 float_get_size (enum float_format format)
119 case FLOAT_IEEE_SINGLE_LE:
120 case FLOAT_IEEE_SINGLE_BE:
125 case FLOAT_IEEE_DOUBLE_LE:
126 case FLOAT_IEEE_DOUBLE_BE:
133 return sizeof (struct fp);
142 /* Attempts to identify the floating point format(s) in which the
143 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
144 Returns the number of matches, which may be zero, one, or
145 greater than one. If a positive value is returned, then the
146 most likely candidate format (based on how common the formats
147 are in practice) is stored in *BEST_GUESS. */
149 float_identify (double expected_value, const void *number, size_t length,
150 enum float_format *best_guess)
152 /* Candidates for identification in order of decreasing
154 enum float_format candidates[] =
156 FLOAT_IEEE_SINGLE_LE,
157 FLOAT_IEEE_SINGLE_BE,
158 FLOAT_IEEE_DOUBLE_LE,
159 FLOAT_IEEE_DOUBLE_BE,
166 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
168 enum float_format *p;
172 for (p = candidates; p < candidates + candidate_cnt; p++)
173 if (float_get_size (*p) == length)
176 assert (sizeof tmp >= float_get_size (*p));
177 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
178 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
184 /* Returns CNT bits in X starting from the given bit OFS. */
185 static inline uint64_t
186 get_bits (uint64_t x, int ofs, int cnt)
188 assert (ofs >= 0 && ofs < 64);
189 assert (cnt > 0 && cnt < 64);
190 assert (ofs + cnt <= 64);
191 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
194 /* Returns the 16-bit unsigned integer at P,
195 which need not be aligned. */
196 static inline uint16_t
197 get_uint16 (const void *p)
200 memcpy (&x, p, sizeof x);
204 /* Returns the 32-bit unsigned integer at P,
205 which need not be aligned. */
206 static inline uint32_t
207 get_uint32 (const void *p)
210 memcpy (&x, p, sizeof x);
214 /* Returns the 64-bit unsigned integer at P,
215 which need not be aligned. */
216 static inline uint64_t
217 get_uint64 (const void *p)
220 memcpy (&x, p, sizeof x);
224 /* Stores 16-bit unsigned integer X at P,
225 which need not be aligned. */
227 put_uint16 (uint16_t x, void *p)
229 memcpy (p, &x, sizeof x);
232 /* Stores 32-bit unsigned integer X at P,
233 which need not be aligned. */
235 put_uint32 (uint32_t x, void *p)
237 memcpy (p, &x, sizeof x);
240 /* Stores 64-bit unsigned integer X at P,
241 which need not be aligned. */
243 put_uint64 (uint64_t x, void *p)
245 memcpy (p, &x, sizeof x);
248 /* Returns NATIVE converted to a form that, when stored in
249 memory, will be in little-endian byte order. */
250 static inline uint16_t
251 native_to_le16 (uint16_t native)
253 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_16 (native);
256 /* Returns NATIVE converted to a form that, when stored in
257 memory, will be in big-endian byte order. */
258 static inline uint16_t
259 native_to_be16 (uint16_t native)
261 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_16 (native);
264 /* Returns NATIVE converted to a form that, when stored in
265 memory, will be in VAX-endian byte order. */
266 static inline uint16_t
267 native_to_vax16 (uint16_t native)
269 return native_to_le16 (native);
272 /* Returns NATIVE converted to a form that, when stored in
273 memory, will be in little-endian byte order. */
274 static inline uint32_t
275 native_to_le32 (uint32_t native)
277 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
280 /* Returns NATIVE converted to a form that, when stored in
281 memory, will be in big-endian byte order. */
282 static inline uint32_t
283 native_to_be32 (uint32_t native)
285 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
288 /* Returns NATIVE converted to a form that, when stored in
289 memory, will be in VAX-endian byte order. */
290 static inline uint32_t
291 native_to_vax32 (uint32_t native)
293 return native_to_be32 (((native & 0xff00ff00) >> 8) |
294 ((native & 0x00ff00ff) << 8));
297 /* Returns NATIVE converted to a form that, when stored in
298 memory, will be in little-endian byte order. */
299 static inline uint64_t
300 native_to_le64 (uint64_t native)
302 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
305 /* Returns NATIVE converted to a form that, when stored in
306 memory, will be in big-endian byte order. */
307 static inline uint64_t
308 native_to_be64 (uint64_t native)
310 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
313 /* Returns NATIVE converted to a form that, when stored in
314 memory, will be in VAX-endian byte order. */
315 static inline uint64_t
316 native_to_vax64 (uint64_t native)
318 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
319 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
320 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
321 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
324 /* Given LE, obtained from memory in little-endian format,
325 returns its value. */
326 static inline uint16_t
327 le_to_native16 (uint16_t le)
329 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_16 (le);
332 /* Given BE, obtained from memory in big-endian format, returns
334 static inline uint16_t
335 be_to_native16 (uint16_t be)
337 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_16 (be);
340 /* Given VAX, obtained from memory in VAX-endian format, returns
342 static inline uint16_t
343 vax_to_native16 (uint16_t vax)
345 return le_to_native16 (vax);
348 /* Given LE, obtained from memory in little-endian format,
349 returns its value. */
350 static inline uint32_t
351 le_to_native32 (uint32_t le)
353 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
356 /* Given BE, obtained from memory in big-endian format, returns
358 static inline uint32_t
359 be_to_native32 (uint32_t be)
361 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
364 /* Given VAX, obtained from memory in VAX-endian format, returns
366 static inline uint32_t
367 vax_to_native32 (uint32_t vax)
369 uint32_t be = be_to_native32 (vax);
370 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
373 /* Given LE, obtained from memory in little-endian format,
374 returns its value. */
375 static inline uint64_t
376 le_to_native64 (uint64_t le)
378 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
381 /* Given BE, obtained from memory in big-endian format, returns
383 static inline uint64_t
384 be_to_native64 (uint64_t be)
386 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
389 /* Given VAX, obtained from memory in VAX-endian format, returns
391 static inline uint64_t
392 vax_to_native64 (uint64_t vax)
394 uint64_t be = be_to_native64 (vax);
395 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
396 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
397 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
398 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
401 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
402 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
403 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
404 static void extract_hex (const char *, struct fp *);
406 /* Converts the number at BITS from format TYPE into neutral
409 extract_number (enum float_format type, const void *bits, struct fp *fp)
413 case FLOAT_IEEE_SINGLE_LE:
414 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
416 case FLOAT_IEEE_SINGLE_BE:
417 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
419 case FLOAT_IEEE_DOUBLE_LE:
420 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
422 case FLOAT_IEEE_DOUBLE_BE:
423 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
427 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
430 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
433 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
437 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
440 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
444 memcpy (fp, bits, sizeof *fp);
447 extract_hex (bits, fp);
451 assert (!(fp->class == FINITE && fp->fraction == 0));
454 /* Converts the IEEE format number in BITS, which has EXP_BITS of
455 exponent and FRAC_BITS of fraction, into neutral format at
458 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
460 const int bias = (1 << (exp_bits - 1)) - 1;
461 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
462 const int max_raw_exp = (1 << exp_bits) - 1;
464 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
465 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
466 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
468 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
470 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
471 fp->class = raw_sign ? MISSING : HIGHEST;
472 else if (raw_exp == max_raw_exp)
475 fp->class = INFINITE;
479 fp->fraction = raw_frac << (64 - frac_bits);
482 else if (raw_exp == 0)
487 fp->exponent = 1 - bias;
488 fp->fraction = raw_frac << (64 - frac_bits);
496 fp->exponent = raw_exp - bias + 1;
497 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
500 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
503 /* Converts the VAX format number in BITS, which has EXP_BITS of
504 exponent and FRAC_BITS of fraction, into neutral format at
507 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
509 const int bias = 1 << (exp_bits - 1);
510 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
511 const int max_raw_exp = (1 << exp_bits) - 1;
513 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
514 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
515 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
517 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
519 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
520 fp->class = raw_sign ? MISSING : HIGHEST;
521 else if (raw_exp == 0)
522 fp->class = raw_sign == 0 ? ZERO : RESERVED;
526 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
527 fp->exponent = raw_exp - bias;
530 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
533 /* Converts the Z architecture format number in BITS, which has
534 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
537 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
539 const int bias = 1 << (exp_bits - 1);
540 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
541 const int max_raw_exp = (1 << exp_bits) - 1;
543 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
544 int raw_exp = get_bits (bits, frac_bits, exp_bits);
545 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
547 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
548 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
549 fp->class = raw_sign ? MISSING : HIGHEST;
550 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
552 else if (raw_frac != 0)
555 fp->fraction = raw_frac << (64 - frac_bits);
556 fp->exponent = (raw_exp - bias) * 4;
562 /* Returns the integer value of hex digit C. */
566 const char s[] = "0123456789abcdef";
567 const char *cp = strchr (s, tolower ((unsigned char) c));
573 /* Parses a hexadecimal floating point number string at S (useful
574 for testing) into neutral format at FP. */
576 extract_hex (const char *s, struct fp *fp)
586 if (!strcmp (s, "Infinity"))
587 fp->class = INFINITE;
588 else if (!strcmp (s, "Missing"))
590 else if (!strcmp (s, "Lowest"))
592 else if (!strcmp (s, "Highest"))
594 else if (!strcmp (s, "Reserved"))
595 fp->class = RESERVED;
600 if (!memcmp (s, "NaN:", 4))
614 for (; isxdigit ((unsigned char) *s); s++)
617 uint64_t digit = hexit_value (*s);
618 fp->fraction += digit << offset;
622 if (fp->class == FINITE)
624 if (fp->fraction == 0)
629 fp->exponent += strtol (s + 1, &tail, 10);
636 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
637 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
638 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
639 static void assemble_hex (struct fp *, void *);
641 /* Converts the neutral format floating point number in FP into
642 format TYPE at NUMBER. May modify FP as part of the
645 assemble_number (enum float_format type, struct fp *fp, void *number)
649 case FLOAT_IEEE_SINGLE_LE:
650 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
652 case FLOAT_IEEE_SINGLE_BE:
653 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
655 case FLOAT_IEEE_DOUBLE_LE:
656 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
658 case FLOAT_IEEE_DOUBLE_BE:
659 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
663 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
666 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
669 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
673 put_uint64 (native_to_be32 (assemble_z (fp, 7, 24)), number);
676 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
680 memcpy (number, fp, sizeof *fp);
683 assemble_hex (fp, number);
688 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
689 Halfway values are rounded to even. */
691 normalize_and_round_fp (struct fp *fp, int frac_bits)
693 assert (fp->class == FINITE);
694 assert (fp->fraction != 0);
696 /* Make sure that the leading fraction bit is 1. */
697 while (!(fp->fraction & (UINT64_C(1) << 63)))
705 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
706 uint64_t decision_bit = last_frac_bit >> 1;
707 if (fp->fraction & decision_bit
708 && (fp->fraction & (decision_bit - 1)
709 || fp->fraction & last_frac_bit))
711 fp->fraction += last_frac_bit;
712 if ((fp->fraction >> 63) == 0)
714 fp->fraction = UINT64_C(1) << 63;
719 /* Mask off all but FRAC_BITS high-order bits.
720 If we rounded up, then these bits no longer have
721 meaningful values. */
722 fp->fraction &= ~(last_frac_bit - 1);
726 /* Converts the neutral format floating point number in FP into
727 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
728 bits, and returns the value. */
730 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
732 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
734 const int bias = (1 << (exp_bits - 1)) - 1;
735 const int max_raw_exp = (1 << exp_bits) - 1;
736 const int min_norm_exp = 1 - bias;
737 const int min_denorm_exp = min_norm_exp - frac_bits;
738 const int max_norm_exp = max_raw_exp - 1 - bias;
744 raw_sign = fp->sign != POSITIVE;
749 normalize_and_round_fp (fp, frac_bits + 1);
750 if (fp->exponent - 1 > max_norm_exp)
752 /* Overflow to infinity. */
753 raw_exp = max_raw_exp;
756 else if (fp->exponent - 1 >= min_norm_exp)
759 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
760 raw_exp = (fp->exponent - 1) + bias;
762 else if (fp->exponent - 1 >= min_denorm_exp)
765 const int denorm_shift = min_norm_exp - fp->exponent;
766 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
771 /* Underflow to zero. */
779 raw_exp = max_raw_exp;
783 raw_frac = fp->fraction >> (64 - frac_bits);
786 raw_exp = max_raw_exp;
796 raw_exp = max_raw_exp - 1;
797 raw_frac = max_raw_frac;
802 raw_exp = max_raw_exp - 1;
803 raw_frac = max_raw_frac - 1;
808 raw_exp = max_raw_exp - 1;
809 raw_frac = max_raw_frac;
813 /* Convert to what processors commonly treat as signaling NAN. */
814 raw_frac = (UINT64_C(1) << frac_bits) - 1;
815 raw_exp = max_raw_exp;
822 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
823 | ((uint64_t) raw_exp << frac_bits)
827 /* Converts the neutral format floating point number in FP into
828 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
829 bits, and returns the value. */
831 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
833 const int max_raw_exp = (1 << exp_bits) - 1;
834 const int bias = 1 << (exp_bits - 1);
835 const int min_finite_exp = 1 - bias;
836 const int max_finite_exp = max_raw_exp - bias;
837 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
843 raw_sign = fp->sign != POSITIVE;
848 normalize_and_round_fp (fp, frac_bits + 1);
849 if (fp->exponent > max_finite_exp)
851 /* Overflow to reserved operand. */
856 else if (fp->exponent >= min_finite_exp)
859 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
860 raw_exp = fp->exponent + bias;
864 /* Underflow to zero. */
887 raw_exp = max_finite_exp + bias;
888 raw_frac = max_raw_frac;
893 raw_exp = max_finite_exp + bias;
894 raw_frac = max_raw_frac - 1;
899 raw_exp = max_finite_exp + bias;
900 raw_frac = max_raw_frac;
907 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
908 | ((uint64_t) raw_exp << frac_bits)
912 /* Shift right until the exponent is a multiple of 4.
913 Rounding is not needed, because none of the formats we support
914 has more than 53 bits of precision. That is, we never shift a
915 1-bit off the right end of the fraction. */
917 normalize_hex_fp (struct fp *fp)
919 while (fp->exponent % 4)
926 /* Converts the neutral format floating point number in FP into Z
927 architecture format with EXP_BITS exponent bits and FRAC_BITS
928 fraction bits, and returns the value. */
930 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
932 const int max_raw_exp = (1 << exp_bits) - 1;
933 const int bias = 1 << (exp_bits - 1);
934 const int max_norm_exp = (max_raw_exp - bias) * 4;
935 const int min_norm_exp = -bias * 4;
936 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
938 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
944 raw_sign = fp->sign != POSITIVE;
949 normalize_and_round_fp (fp, frac_bits);
950 normalize_hex_fp (fp);
951 if (fp->exponent > max_norm_exp)
953 /* Overflow to largest value. */
954 raw_exp = max_raw_exp;
955 raw_frac = max_raw_frac;
957 else if (fp->exponent >= min_norm_exp)
960 raw_frac = fp->fraction >> (64 - frac_bits);
961 raw_exp = (fp->exponent / 4) + bias;
963 else if (fp->exponent >= min_denorm_exp)
966 const int denorm_shift = min_norm_exp - fp->exponent;
967 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
972 /* Underflow to zero. */
979 /* Overflow to largest value. */
980 raw_exp = max_raw_exp;
981 raw_frac = max_raw_frac;
987 /* Treat all of these as zero, because Z architecture
988 doesn't have any reserved values. */
995 raw_exp = max_raw_exp;
996 raw_frac = max_raw_frac;
1001 raw_exp = max_raw_exp;
1002 raw_frac = max_raw_frac - 1;
1007 raw_exp = max_raw_exp;
1008 raw_frac = max_raw_frac;
1015 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
1016 | ((uint64_t) raw_exp << frac_bits)
1020 /* Converts the neutral format floating point number in FP into a
1021 null-terminated human-readable hex string in OUTPUT. */
1023 assemble_hex (struct fp *fp, void *output)
1028 if (fp->sign == NEGATIVE)
1034 normalize_and_round_fp (fp, 64);
1035 normalize_hex_fp (fp);
1036 assert (fp->fraction != 0);
1039 while (fp->fraction != 0)
1041 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1044 if (fp->exponent != 0)
1045 sprintf (s, "p%d", fp->exponent);
1049 strcpy (s, "Infinity");
1053 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1061 strcpy (buffer, "Missing");
1065 strcpy (buffer, "Lowest");
1069 strcpy (buffer, "Highest");
1073 strcpy (s, "Reserved");
1077 strncpy (output, buffer, float_get_size (FLOAT_HEX));