1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <libpspp/float-format.h>
27 #include <libpspp/assertion.h>
28 #include <libpspp/integer-format.h>
29 #include <libpspp/str.h>
34 /* Neutral intermediate representation for binary floating-point numbers. */
39 FINITE, /* Finite number (normalized or denormalized). */
40 INFINITE, /* Positive or negative infinity. */
41 NAN, /* Not a number. */
43 ZERO, /* Positive or negative zero. */
44 MISSING, /* System missing. */
45 LOWEST, /* LOWEST on e.g. missing values. */
46 HIGHEST, /* HIGHEST on e.g. missing values. */
47 RESERVED /* Special Vax representation. */
58 /* class == FINITE: The number has value "fraction *
59 2**exponent", considering bit 63 in fraction to be just
60 right of the decimal point.
62 class == NAN: The fraction holds the significand, with its
63 leftmost bit in bit 63, so that signaling and quiet NaN
64 values can be preserved.
66 Unused for other classes. */
71 static void extract_number (enum float_format, const void *, struct fp *);
72 static void assemble_number (enum float_format, struct fp *, void *);
74 static inline uint16_t get_uint16 (const void *);
75 static inline uint32_t get_uint32 (const void *);
76 static inline uint64_t get_uint64 (const void *);
78 static inline void put_uint16 (uint16_t, void *);
79 static inline void put_uint32 (uint32_t, void *);
80 static inline void put_uint64 (uint64_t, void *);
82 /* Converts SRC from format FROM to format TO, storing the
83 converted value into DST.
84 SRC and DST are permitted to arbitrarily overlap. */
86 float_convert (enum float_format from, const void *src,
87 enum float_format to, void *dst)
91 if ((from == FLOAT_IEEE_SINGLE_LE || from == FLOAT_IEEE_SINGLE_BE)
92 && (to == FLOAT_IEEE_SINGLE_LE || to == FLOAT_IEEE_SINGLE_BE))
93 put_uint32 (bswap_32 (get_uint32 (src)), dst);
94 else if ((from == FLOAT_IEEE_DOUBLE_LE || from == FLOAT_IEEE_DOUBLE_BE)
95 && (to == FLOAT_IEEE_DOUBLE_LE || to == FLOAT_IEEE_DOUBLE_BE))
96 put_uint64 (bswap_64 (get_uint64 (src)), dst);
100 extract_number (from, src, &fp);
101 assemble_number (to, &fp, dst);
107 memmove (dst, src, float_get_size (from));
111 /* Returns the number of bytes in a number in the given
114 float_get_size (enum float_format format)
118 case FLOAT_IEEE_SINGLE_LE:
119 case FLOAT_IEEE_SINGLE_BE:
124 case FLOAT_IEEE_DOUBLE_LE:
125 case FLOAT_IEEE_DOUBLE_BE:
132 return sizeof (struct fp);
141 /* Attempts to identify the floating point format(s) in which the
142 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
143 Returns the number of matches, which may be zero, one, or
144 greater than one. If a positive value is returned, then the
145 most likely candidate format (based on how common the formats
146 are in practice) is stored in *BEST_GUESS. */
148 float_identify (double expected_value, const void *number, size_t length,
149 enum float_format *best_guess)
151 /* Candidates for identification in order of decreasing
153 enum float_format candidates[] =
155 FLOAT_IEEE_SINGLE_LE,
156 FLOAT_IEEE_SINGLE_BE,
157 FLOAT_IEEE_DOUBLE_LE,
158 FLOAT_IEEE_DOUBLE_BE,
165 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
167 enum float_format *p;
171 for (p = candidates; p < candidates + candidate_cnt; p++)
172 if (float_get_size (*p) == length)
175 assert (sizeof tmp >= float_get_size (*p));
176 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
177 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
183 /* Returns CNT bits in X starting from the given bit OFS. */
184 static inline uint64_t
185 get_bits (uint64_t x, int ofs, int cnt)
187 assert (ofs >= 0 && ofs < 64);
188 assert (cnt > 0 && cnt < 64);
189 assert (ofs + cnt <= 64);
190 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
193 /* Returns the 16-bit unsigned integer at P,
194 which need not be aligned. */
195 static inline uint16_t
196 get_uint16 (const void *p)
199 memcpy (&x, p, sizeof x);
203 /* Returns the 32-bit unsigned integer at P,
204 which need not be aligned. */
205 static inline uint32_t
206 get_uint32 (const void *p)
209 memcpy (&x, p, sizeof x);
213 /* Returns the 64-bit unsigned integer at P,
214 which need not be aligned. */
215 static inline uint64_t
216 get_uint64 (const void *p)
219 memcpy (&x, p, sizeof x);
223 /* Stores 16-bit unsigned integer X at P,
224 which need not be aligned. */
226 put_uint16 (uint16_t x, void *p)
228 memcpy (p, &x, sizeof x);
231 /* Stores 32-bit unsigned integer X at P,
232 which need not be aligned. */
234 put_uint32 (uint32_t x, void *p)
236 memcpy (p, &x, sizeof x);
239 /* Stores 64-bit unsigned integer X at P,
240 which need not be aligned. */
242 put_uint64 (uint64_t x, void *p)
244 memcpy (p, &x, sizeof x);
247 /* Returns NATIVE converted to a form that, when stored in
248 memory, will be in little-endian byte order. */
249 static inline uint16_t
250 native_to_le16 (uint16_t native)
252 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_16 (native);
255 /* Returns NATIVE converted to a form that, when stored in
256 memory, will be in big-endian byte order. */
257 static inline uint16_t
258 native_to_be16 (uint16_t native)
260 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_16 (native);
263 /* Returns NATIVE converted to a form that, when stored in
264 memory, will be in VAX-endian byte order. */
265 static inline uint16_t
266 native_to_vax16 (uint16_t native)
268 return native_to_le16 (native);
271 /* Returns NATIVE converted to a form that, when stored in
272 memory, will be in little-endian byte order. */
273 static inline uint32_t
274 native_to_le32 (uint32_t native)
276 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
279 /* Returns NATIVE converted to a form that, when stored in
280 memory, will be in big-endian byte order. */
281 static inline uint32_t
282 native_to_be32 (uint32_t native)
284 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
287 /* Returns NATIVE converted to a form that, when stored in
288 memory, will be in VAX-endian byte order. */
289 static inline uint32_t
290 native_to_vax32 (uint32_t native)
292 return native_to_be32 (((native & 0xff00ff00) >> 8) |
293 ((native & 0x00ff00ff) << 8));
296 /* Returns NATIVE converted to a form that, when stored in
297 memory, will be in little-endian byte order. */
298 static inline uint64_t
299 native_to_le64 (uint64_t native)
301 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
304 /* Returns NATIVE converted to a form that, when stored in
305 memory, will be in big-endian byte order. */
306 static inline uint64_t
307 native_to_be64 (uint64_t native)
309 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
312 /* Returns NATIVE converted to a form that, when stored in
313 memory, will be in VAX-endian byte order. */
314 static inline uint64_t
315 native_to_vax64 (uint64_t native)
317 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
318 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
319 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
320 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
323 /* Given LE, obtained from memory in little-endian format,
324 returns its value. */
325 static inline uint16_t
326 le_to_native16 (uint16_t le)
328 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_16 (le);
331 /* Given BE, obtained from memory in big-endian format, returns
333 static inline uint16_t
334 be_to_native16 (uint16_t be)
336 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_16 (be);
339 /* Given VAX, obtained from memory in VAX-endian format, returns
341 static inline uint16_t
342 vax_to_native16 (uint16_t vax)
344 return le_to_native16 (vax);
347 /* Given LE, obtained from memory in little-endian format,
348 returns its value. */
349 static inline uint32_t
350 le_to_native32 (uint32_t le)
352 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
355 /* Given BE, obtained from memory in big-endian format, returns
357 static inline uint32_t
358 be_to_native32 (uint32_t be)
360 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
363 /* Given VAX, obtained from memory in VAX-endian format, returns
365 static inline uint32_t
366 vax_to_native32 (uint32_t vax)
368 uint32_t be = be_to_native32 (vax);
369 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
372 /* Given LE, obtained from memory in little-endian format,
373 returns its value. */
374 static inline uint64_t
375 le_to_native64 (uint64_t le)
377 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
380 /* Given BE, obtained from memory in big-endian format, returns
382 static inline uint64_t
383 be_to_native64 (uint64_t be)
385 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
388 /* Given VAX, obtained from memory in VAX-endian format, returns
390 static inline uint64_t
391 vax_to_native64 (uint64_t vax)
393 uint64_t be = be_to_native64 (vax);
394 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
395 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
396 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
397 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
400 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
401 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
402 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
403 static void extract_hex (const char *, struct fp *);
405 /* Converts the number at BITS from format TYPE into neutral
408 extract_number (enum float_format type, const void *bits, struct fp *fp)
412 case FLOAT_IEEE_SINGLE_LE:
413 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
415 case FLOAT_IEEE_SINGLE_BE:
416 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
418 case FLOAT_IEEE_DOUBLE_LE:
419 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
421 case FLOAT_IEEE_DOUBLE_BE:
422 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
426 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
429 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
432 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
436 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
439 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
443 memcpy (fp, bits, sizeof *fp);
446 extract_hex (bits, fp);
450 assert (!(fp->class == FINITE && fp->fraction == 0));
453 /* Converts the IEEE format number in BITS, which has EXP_BITS of
454 exponent and FRAC_BITS of fraction, into neutral format at
457 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
459 const int bias = (1 << (exp_bits - 1)) - 1;
460 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
461 const int max_raw_exp = (1 << exp_bits) - 1;
463 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
464 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
465 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
467 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
469 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
470 fp->class = raw_sign ? MISSING : HIGHEST;
471 else if (raw_exp == max_raw_exp)
474 fp->class = INFINITE;
478 fp->fraction = raw_frac << (64 - frac_bits);
481 else if (raw_exp == 0)
486 fp->exponent = 1 - bias;
487 fp->fraction = raw_frac << (64 - frac_bits);
495 fp->exponent = raw_exp - bias + 1;
496 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
499 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
502 /* Converts the VAX format number in BITS, which has EXP_BITS of
503 exponent and FRAC_BITS of fraction, into neutral format at
506 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
508 const int bias = 1 << (exp_bits - 1);
509 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
510 const int max_raw_exp = (1 << exp_bits) - 1;
512 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
513 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
514 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
516 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
518 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
519 fp->class = raw_sign ? MISSING : HIGHEST;
520 else if (raw_exp == 0)
521 fp->class = raw_sign == 0 ? ZERO : RESERVED;
525 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
526 fp->exponent = raw_exp - bias;
529 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
532 /* Converts the Z architecture format number in BITS, which has
533 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
536 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
538 const int bias = 1 << (exp_bits - 1);
539 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
540 const int max_raw_exp = (1 << exp_bits) - 1;
542 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
543 int raw_exp = get_bits (bits, frac_bits, exp_bits);
544 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
546 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
547 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
548 fp->class = raw_sign ? MISSING : HIGHEST;
549 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
551 else if (raw_frac != 0)
554 fp->fraction = raw_frac << (64 - frac_bits);
555 fp->exponent = (raw_exp - bias) * 4;
561 /* Returns the integer value of hex digit C. */
565 const char s[] = "0123456789abcdef";
566 const char *cp = strchr (s, tolower ((unsigned char) c));
572 /* Parses a hexadecimal floating point number string at S (useful
573 for testing) into neutral format at FP. */
575 extract_hex (const char *s, struct fp *fp)
585 if (!strcmp (s, "Infinity"))
586 fp->class = INFINITE;
587 else if (!strcmp (s, "Missing"))
589 else if (!strcmp (s, "Lowest"))
591 else if (!strcmp (s, "Highest"))
593 else if (!strcmp (s, "Reserved"))
594 fp->class = RESERVED;
599 if (!memcmp (s, "NaN:", 4))
613 for (; isxdigit ((unsigned char) *s); s++)
616 uint64_t digit = hexit_value (*s);
617 fp->fraction += digit << offset;
621 if (fp->class == FINITE)
623 if (fp->fraction == 0)
628 fp->exponent += strtol (s + 1, &tail, 10);
635 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
636 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
637 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
638 static void assemble_hex (struct fp *, void *);
640 /* Converts the neutral format floating point number in FP into
641 format TYPE at NUMBER. May modify FP as part of the
644 assemble_number (enum float_format type, struct fp *fp, void *number)
648 case FLOAT_IEEE_SINGLE_LE:
649 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
651 case FLOAT_IEEE_SINGLE_BE:
652 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
654 case FLOAT_IEEE_DOUBLE_LE:
655 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
657 case FLOAT_IEEE_DOUBLE_BE:
658 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
662 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
665 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
668 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
672 put_uint64 (native_to_be32 (assemble_z (fp, 7, 24)), number);
675 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
679 memcpy (number, fp, sizeof *fp);
682 assemble_hex (fp, number);
687 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
688 Halfway values are rounded to even. */
690 normalize_and_round_fp (struct fp *fp, int frac_bits)
692 assert (fp->class == FINITE);
693 assert (fp->fraction != 0);
695 /* Make sure that the leading fraction bit is 1. */
696 while (!(fp->fraction & (UINT64_C(1) << 63)))
704 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
705 uint64_t decision_bit = last_frac_bit >> 1;
706 if (fp->fraction & decision_bit
707 && (fp->fraction & (decision_bit - 1)
708 || fp->fraction & last_frac_bit))
710 fp->fraction += last_frac_bit;
711 if ((fp->fraction >> 63) == 0)
713 fp->fraction = UINT64_C(1) << 63;
718 /* Mask off all but FRAC_BITS high-order bits.
719 If we rounded up, then these bits no longer have
720 meaningful values. */
721 fp->fraction &= ~(last_frac_bit - 1);
725 /* Converts the neutral format floating point number in FP into
726 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
727 bits, and returns the value. */
729 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
731 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
733 const int bias = (1 << (exp_bits - 1)) - 1;
734 const int max_raw_exp = (1 << exp_bits) - 1;
735 const int min_norm_exp = 1 - bias;
736 const int min_denorm_exp = min_norm_exp - frac_bits;
737 const int max_norm_exp = max_raw_exp - 1 - bias;
743 raw_sign = fp->sign != POSITIVE;
748 normalize_and_round_fp (fp, frac_bits + 1);
749 if (fp->exponent - 1 > max_norm_exp)
751 /* Overflow to infinity. */
752 raw_exp = max_raw_exp;
755 else if (fp->exponent - 1 >= min_norm_exp)
758 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
759 raw_exp = (fp->exponent - 1) + bias;
761 else if (fp->exponent - 1 >= min_denorm_exp)
764 const int denorm_shift = min_norm_exp - fp->exponent;
765 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
770 /* Underflow to zero. */
778 raw_exp = max_raw_exp;
782 raw_frac = fp->fraction >> (64 - frac_bits);
785 raw_exp = max_raw_exp;
795 raw_exp = max_raw_exp - 1;
796 raw_frac = max_raw_frac;
801 raw_exp = max_raw_exp - 1;
802 raw_frac = max_raw_frac - 1;
807 raw_exp = max_raw_exp - 1;
808 raw_frac = max_raw_frac;
812 /* Convert to what processors commonly treat as signaling NAN. */
813 raw_frac = (UINT64_C(1) << frac_bits) - 1;
814 raw_exp = max_raw_exp;
821 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
822 | ((uint64_t) raw_exp << frac_bits)
826 /* Converts the neutral format floating point number in FP into
827 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
828 bits, and returns the value. */
830 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
832 const int max_raw_exp = (1 << exp_bits) - 1;
833 const int bias = 1 << (exp_bits - 1);
834 const int min_finite_exp = 1 - bias;
835 const int max_finite_exp = max_raw_exp - bias;
836 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
842 raw_sign = fp->sign != POSITIVE;
847 normalize_and_round_fp (fp, frac_bits + 1);
848 if (fp->exponent > max_finite_exp)
850 /* Overflow to reserved operand. */
855 else if (fp->exponent >= min_finite_exp)
858 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
859 raw_exp = fp->exponent + bias;
863 /* Underflow to zero. */
886 raw_exp = max_finite_exp + bias;
887 raw_frac = max_raw_frac;
892 raw_exp = max_finite_exp + bias;
893 raw_frac = max_raw_frac - 1;
898 raw_exp = max_finite_exp + bias;
899 raw_frac = max_raw_frac;
906 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
907 | ((uint64_t) raw_exp << frac_bits)
911 /* Shift right until the exponent is a multiple of 4.
912 Rounding is not needed, because none of the formats we support
913 has more than 53 bits of precision. That is, we never shift a
914 1-bit off the right end of the fraction. */
916 normalize_hex_fp (struct fp *fp)
918 while (fp->exponent % 4)
925 /* Converts the neutral format floating point number in FP into Z
926 architecture format with EXP_BITS exponent bits and FRAC_BITS
927 fraction bits, and returns the value. */
929 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
931 const int max_raw_exp = (1 << exp_bits) - 1;
932 const int bias = 1 << (exp_bits - 1);
933 const int max_norm_exp = (max_raw_exp - bias) * 4;
934 const int min_norm_exp = -bias * 4;
935 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
937 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
943 raw_sign = fp->sign != POSITIVE;
948 normalize_and_round_fp (fp, frac_bits);
949 normalize_hex_fp (fp);
950 if (fp->exponent > max_norm_exp)
952 /* Overflow to largest value. */
953 raw_exp = max_raw_exp;
954 raw_frac = max_raw_frac;
956 else if (fp->exponent >= min_norm_exp)
959 raw_frac = fp->fraction >> (64 - frac_bits);
960 raw_exp = (fp->exponent / 4) + bias;
962 else if (fp->exponent >= min_denorm_exp)
965 const int denorm_shift = min_norm_exp - fp->exponent;
966 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
971 /* Underflow to zero. */
978 /* Overflow to largest value. */
979 raw_exp = max_raw_exp;
980 raw_frac = max_raw_frac;
986 /* Treat all of these as zero, because Z architecture
987 doesn't have any reserved values. */
994 raw_exp = max_raw_exp;
995 raw_frac = max_raw_frac;
1000 raw_exp = max_raw_exp;
1001 raw_frac = max_raw_frac - 1;
1006 raw_exp = max_raw_exp;
1007 raw_frac = max_raw_frac;
1014 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
1015 | ((uint64_t) raw_exp << frac_bits)
1019 /* Converts the neutral format floating point number in FP into a
1020 null-terminated human-readable hex string in OUTPUT. */
1022 assemble_hex (struct fp *fp, void *output)
1027 if (fp->sign == NEGATIVE)
1033 normalize_and_round_fp (fp, 64);
1034 normalize_hex_fp (fp);
1035 assert (fp->fraction != 0);
1038 while (fp->fraction != 0)
1040 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1043 if (fp->exponent != 0)
1044 sprintf (s, "p%d", fp->exponent);
1048 strcpy (s, "Infinity");
1052 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1060 strcpy (buffer, "Missing");
1064 strcpy (buffer, "Lowest");
1068 strcpy (buffer, "Highest");
1072 strcpy (s, "Reserved");
1076 strncpy (output, buffer, float_get_size (FLOAT_HEX));