1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU 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, see <http://www.gnu.org/licenses/>. */
19 #include "libpspp/float-format.h"
27 #include "libpspp/assertion.h"
28 #include "libpspp/integer-format.h"
31 /* Neutral intermediate representation for binary floating-point numbers. */
36 FINITE, /* Finite number (normalized or denormalized). */
37 INFINITE, /* Positive or negative infinity. */
38 NAN, /* Not a number. */
40 ZERO, /* Positive or negative zero. */
41 MISSING, /* System missing. */
42 LOWEST, /* LOWEST on e.g. missing values. */
43 HIGHEST, /* HIGHEST on e.g. missing values. */
44 RESERVED /* Special Vax representation. */
55 /* class == FINITE: The number has value "fraction *
56 2**exponent", considering bit 63 in fraction to be just
57 right of the decimal point.
59 class == NAN: The fraction holds the significand, with its
60 leftmost bit in bit 63, so that signaling and quiet NaN
61 values can be preserved.
63 Unused for other classes. */
68 static void extract_number (enum float_format, const void *, struct fp *);
69 static void assemble_number (enum float_format, struct fp *, void *);
71 static inline uint32_t get_uint32 (const void *);
72 static inline uint64_t get_uint64 (const void *);
74 static inline void put_uint32 (uint32_t, void *);
75 static inline void put_uint64 (uint64_t, void *);
77 /* Converts SRC from format FROM to format TO, storing the
78 converted value into DST.
79 SRC and DST are permitted to arbitrarily overlap. */
81 float_convert (enum float_format from, const void *src,
82 enum float_format to, void *dst)
86 if ((from == FLOAT_IEEE_SINGLE_LE || from == FLOAT_IEEE_SINGLE_BE)
87 && (to == FLOAT_IEEE_SINGLE_LE || to == FLOAT_IEEE_SINGLE_BE))
88 put_uint32 (bswap_32 (get_uint32 (src)), dst);
89 else if ((from == FLOAT_IEEE_DOUBLE_LE || from == FLOAT_IEEE_DOUBLE_BE)
90 && (to == FLOAT_IEEE_DOUBLE_LE || to == FLOAT_IEEE_DOUBLE_BE))
91 put_uint64 (bswap_64 (get_uint64 (src)), dst);
95 extract_number (from, src, &fp);
96 assemble_number (to, &fp, dst);
102 memmove (dst, src, float_get_size (from));
106 /* Converts SRC from format FROM to a native double and returns
109 float_get_double (enum float_format from, const void *src)
112 float_convert (from, src, FLOAT_NATIVE_DOUBLE, &dst);
116 /* Returns the number of bytes in a number in the given
119 float_get_size (enum float_format format)
123 case FLOAT_IEEE_SINGLE_LE:
124 case FLOAT_IEEE_SINGLE_BE:
129 case FLOAT_IEEE_DOUBLE_LE:
130 case FLOAT_IEEE_DOUBLE_BE:
137 return sizeof (struct fp);
146 /* Attempts to identify the floating point format(s) in which the
147 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
148 Returns the number of matches, which may be zero, one, or
149 greater than one. If a positive value is returned, then the
150 most likely candidate format (based on how common the formats
151 are in practice) is stored in *BEST_GUESS. */
153 float_identify (double expected_value, const void *number, size_t length,
154 enum float_format *best_guess)
156 /* Candidates for identification in order of decreasing
158 enum float_format candidates[] =
160 FLOAT_IEEE_SINGLE_LE,
161 FLOAT_IEEE_SINGLE_BE,
162 FLOAT_IEEE_DOUBLE_LE,
163 FLOAT_IEEE_DOUBLE_BE,
170 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
172 enum float_format *p;
176 for (p = candidates; p < candidates + candidate_cnt; p++)
177 if (float_get_size (*p) == length)
180 assert (sizeof tmp >= float_get_size (*p));
181 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
182 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
188 /* Returns the double value that is just greater than -DBL_MAX,
189 which in PSPP syntax files is called LOWEST and used as the
190 low end of numeric ranges that are supposed to be unbounded on
191 the low end, as in the missing value set created by,
192 e.g. MISSING VALUES X(LOWEST THRU 5). (-DBL_MAX is used for
193 SYSMIS so it is not available for LOWEST.) */
195 float_get_lowest (void)
202 assemble_number (FLOAT_NATIVE_DOUBLE, &fp, &x);
206 /* Returns CNT bits in X starting from the given bit OFS. */
207 static inline uint64_t
208 get_bits (uint64_t x, int ofs, int cnt)
210 assert (ofs >= 0 && ofs < 64);
211 assert (cnt > 0 && cnt < 64);
212 assert (ofs + cnt <= 64);
213 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
216 /* Returns the 32-bit unsigned integer at P,
217 which need not be aligned. */
218 static inline uint32_t
219 get_uint32 (const void *p)
222 memcpy (&x, p, sizeof x);
226 /* Returns the 64-bit unsigned integer at P,
227 which need not be aligned. */
228 static inline uint64_t
229 get_uint64 (const void *p)
232 memcpy (&x, p, sizeof x);
236 /* Stores 32-bit unsigned integer X at P,
237 which need not be aligned. */
239 put_uint32 (uint32_t x, void *p)
241 memcpy (p, &x, sizeof x);
244 /* Stores 64-bit unsigned integer X at P,
245 which need not be aligned. */
247 put_uint64 (uint64_t x, void *p)
249 memcpy (p, &x, sizeof x);
252 /* Returns NATIVE converted to a form that, when stored in
253 memory, will be in little-endian byte order. */
254 static inline uint32_t
255 native_to_le32 (uint32_t native)
257 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
260 /* Returns NATIVE converted to a form that, when stored in
261 memory, will be in big-endian byte order. */
262 static inline uint32_t
263 native_to_be32 (uint32_t native)
265 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
268 /* Returns NATIVE converted to a form that, when stored in
269 memory, will be in VAX-endian byte order. */
270 static inline uint32_t
271 native_to_vax32 (uint32_t native)
273 return native_to_be32 (((native & 0xff00ff00) >> 8) |
274 ((native & 0x00ff00ff) << 8));
277 /* Returns NATIVE converted to a form that, when stored in
278 memory, will be in little-endian byte order. */
279 static inline uint64_t
280 native_to_le64 (uint64_t native)
282 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
285 /* Returns NATIVE converted to a form that, when stored in
286 memory, will be in big-endian byte order. */
287 static inline uint64_t
288 native_to_be64 (uint64_t native)
290 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
293 /* Returns NATIVE converted to a form that, when stored in
294 memory, will be in VAX-endian byte order. */
295 static inline uint64_t
296 native_to_vax64 (uint64_t native)
298 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
299 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
300 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
301 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
304 /* Given LE, obtained from memory in little-endian format,
305 returns its value. */
306 static inline uint32_t
307 le_to_native32 (uint32_t le)
309 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
312 /* Given BE, obtained from memory in big-endian format, returns
314 static inline uint32_t
315 be_to_native32 (uint32_t be)
317 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
320 /* Given VAX, obtained from memory in VAX-endian format, returns
322 static inline uint32_t
323 vax_to_native32 (uint32_t vax)
325 uint32_t be = be_to_native32 (vax);
326 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
329 /* Given LE, obtained from memory in little-endian format,
330 returns its value. */
331 static inline uint64_t
332 le_to_native64 (uint64_t le)
334 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
337 /* Given BE, obtained from memory in big-endian format, returns
339 static inline uint64_t
340 be_to_native64 (uint64_t be)
342 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
345 /* Given VAX, obtained from memory in VAX-endian format, returns
347 static inline uint64_t
348 vax_to_native64 (uint64_t vax)
350 uint64_t be = be_to_native64 (vax);
351 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
352 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
353 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
354 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
357 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
358 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
359 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
360 static void extract_hex (const char *, struct fp *);
362 /* Converts the number at BITS from format TYPE into neutral
365 extract_number (enum float_format type, const void *bits, struct fp *fp)
369 case FLOAT_IEEE_SINGLE_LE:
370 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
372 case FLOAT_IEEE_SINGLE_BE:
373 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
375 case FLOAT_IEEE_DOUBLE_LE:
376 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
378 case FLOAT_IEEE_DOUBLE_BE:
379 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
383 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
386 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
389 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
393 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
396 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
400 memcpy (fp, bits, sizeof *fp);
403 extract_hex (bits, fp);
407 assert (!(fp->class == FINITE && fp->fraction == 0));
410 /* Converts the IEEE format number in BITS, which has EXP_BITS of
411 exponent and FRAC_BITS of fraction, into neutral format at
414 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
416 const int bias = (1 << (exp_bits - 1)) - 1;
417 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
418 const int max_raw_exp = (1 << exp_bits) - 1;
420 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
421 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
422 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
424 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
426 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
427 fp->class = raw_sign ? MISSING : HIGHEST;
428 else if (raw_exp == max_raw_exp)
431 fp->class = INFINITE;
435 fp->fraction = raw_frac << (64 - frac_bits);
438 else if (raw_exp == 0)
443 fp->exponent = 1 - bias;
444 fp->fraction = raw_frac << (64 - frac_bits);
452 fp->exponent = raw_exp - bias + 1;
453 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
456 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
459 /* Converts the VAX format number in BITS, which has EXP_BITS of
460 exponent and FRAC_BITS of fraction, into neutral format at
463 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
465 const int bias = 1 << (exp_bits - 1);
466 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
467 const int max_raw_exp = (1 << exp_bits) - 1;
469 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
470 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
471 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
473 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
475 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
476 fp->class = raw_sign ? MISSING : HIGHEST;
477 else if (raw_exp == 0)
478 fp->class = raw_sign == 0 ? ZERO : RESERVED;
482 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
483 fp->exponent = raw_exp - bias;
486 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
489 /* Converts the Z architecture format number in BITS, which has
490 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
493 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
495 const int bias = 1 << (exp_bits - 1);
496 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
497 const int max_raw_exp = (1 << exp_bits) - 1;
499 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
500 int raw_exp = get_bits (bits, frac_bits, exp_bits);
501 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
503 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
504 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
505 fp->class = raw_sign ? MISSING : HIGHEST;
506 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
508 else if (raw_frac != 0)
511 fp->fraction = raw_frac << (64 - frac_bits);
512 fp->exponent = (raw_exp - bias) * 4;
518 /* Returns the integer value of hex digit C. */
522 const char s[] = "0123456789abcdef";
523 const char *cp = strchr (s, tolower ((unsigned char) c));
529 /* Parses a hexadecimal floating point number string at S (useful
530 for testing) into neutral format at FP. */
532 extract_hex (const char *s, struct fp *fp)
542 if (!strcmp (s, "Infinity"))
543 fp->class = INFINITE;
544 else if (!strcmp (s, "Missing"))
546 else if (!strcmp (s, "Lowest"))
548 else if (!strcmp (s, "Highest"))
550 else if (!strcmp (s, "Reserved"))
551 fp->class = RESERVED;
556 if (!memcmp (s, "NaN:", 4))
570 for (; isxdigit ((unsigned char) *s); s++)
573 uint64_t digit = hexit_value (*s);
574 fp->fraction += digit << offset;
578 if (fp->class == FINITE)
580 if (fp->fraction == 0)
585 fp->exponent += strtol (s + 1, &tail, 10);
592 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
593 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
594 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
595 static void assemble_hex (struct fp *, void *);
597 /* Converts the neutral format floating point number in FP into
598 format TYPE at NUMBER. May modify FP as part of the
601 assemble_number (enum float_format type, struct fp *fp, void *number)
605 case FLOAT_IEEE_SINGLE_LE:
606 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
608 case FLOAT_IEEE_SINGLE_BE:
609 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
611 case FLOAT_IEEE_DOUBLE_LE:
612 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
614 case FLOAT_IEEE_DOUBLE_BE:
615 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
619 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
622 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
625 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
629 put_uint32 (native_to_be32 (assemble_z (fp, 7, 24)), number);
632 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
636 memcpy (number, fp, sizeof *fp);
639 assemble_hex (fp, number);
644 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
645 Halfway values are rounded to even. */
647 normalize_and_round_fp (struct fp *fp, int frac_bits)
649 assert (fp->class == FINITE);
650 assert (fp->fraction != 0);
652 /* Make sure that the leading fraction bit is 1. */
653 while (!(fp->fraction & (UINT64_C(1) << 63)))
661 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
662 uint64_t decision_bit = last_frac_bit >> 1;
663 if (fp->fraction & decision_bit
664 && (fp->fraction & (decision_bit - 1)
665 || fp->fraction & last_frac_bit))
667 fp->fraction += last_frac_bit;
668 if ((fp->fraction >> 63) == 0)
670 fp->fraction = UINT64_C(1) << 63;
675 /* Mask off all but FRAC_BITS high-order bits.
676 If we rounded up, then these bits no longer have
677 meaningful values. */
678 fp->fraction &= ~(last_frac_bit - 1);
682 /* Converts the neutral format floating point number in FP into
683 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
684 bits, and returns the value. */
686 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
688 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
690 const int bias = (1 << (exp_bits - 1)) - 1;
691 const int max_raw_exp = (1 << exp_bits) - 1;
692 const int min_norm_exp = 1 - bias;
693 const int min_denorm_exp = min_norm_exp - frac_bits;
694 const int max_norm_exp = max_raw_exp - 1 - bias;
700 raw_sign = fp->sign != POSITIVE;
705 normalize_and_round_fp (fp, frac_bits + 1);
706 if (fp->exponent - 1 > max_norm_exp)
708 /* Overflow to infinity. */
709 raw_exp = max_raw_exp;
712 else if (fp->exponent - 1 >= min_norm_exp)
715 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
716 raw_exp = (fp->exponent - 1) + bias;
718 else if (fp->exponent - 1 >= min_denorm_exp)
721 const int denorm_shift = min_norm_exp - fp->exponent;
722 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
727 /* Underflow to zero. */
735 raw_exp = max_raw_exp;
739 raw_frac = fp->fraction >> (64 - frac_bits);
742 raw_exp = max_raw_exp;
752 raw_exp = max_raw_exp - 1;
753 raw_frac = max_raw_frac;
758 raw_exp = max_raw_exp - 1;
759 raw_frac = max_raw_frac - 1;
764 raw_exp = max_raw_exp - 1;
765 raw_frac = max_raw_frac;
769 /* Convert to what processors commonly treat as signaling NAN. */
770 raw_frac = (UINT64_C(1) << frac_bits) - 1;
771 raw_exp = max_raw_exp;
778 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
779 | ((uint64_t) raw_exp << frac_bits)
783 /* Converts the neutral format floating point number in FP into
784 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
785 bits, and returns the value. */
787 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
789 const int max_raw_exp = (1 << exp_bits) - 1;
790 const int bias = 1 << (exp_bits - 1);
791 const int min_finite_exp = 1 - bias;
792 const int max_finite_exp = max_raw_exp - bias;
793 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
799 raw_sign = fp->sign != POSITIVE;
804 normalize_and_round_fp (fp, frac_bits + 1);
805 if (fp->exponent > max_finite_exp)
807 /* Overflow to reserved operand. */
812 else if (fp->exponent >= min_finite_exp)
815 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
816 raw_exp = fp->exponent + bias;
820 /* Underflow to zero. */
843 raw_exp = max_finite_exp + bias;
844 raw_frac = max_raw_frac;
849 raw_exp = max_finite_exp + bias;
850 raw_frac = max_raw_frac - 1;
855 raw_exp = max_finite_exp + bias;
856 raw_frac = max_raw_frac;
863 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
864 | ((uint64_t) raw_exp << frac_bits)
868 /* Shift right until the exponent is a multiple of 4.
869 Rounding is not needed, because none of the formats we support
870 has more than 53 bits of precision. That is, we never shift a
871 1-bit off the right end of the fraction. */
873 normalize_hex_fp (struct fp *fp)
875 while (fp->exponent % 4)
882 /* Converts the neutral format floating point number in FP into Z
883 architecture format with EXP_BITS exponent bits and FRAC_BITS
884 fraction bits, and returns the value. */
886 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
888 const int max_raw_exp = (1 << exp_bits) - 1;
889 const int bias = 1 << (exp_bits - 1);
890 const int max_norm_exp = (max_raw_exp - bias) * 4;
891 const int min_norm_exp = -bias * 4;
892 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
894 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
900 raw_sign = fp->sign != POSITIVE;
905 normalize_and_round_fp (fp, frac_bits);
906 normalize_hex_fp (fp);
907 if (fp->exponent > max_norm_exp)
909 /* Overflow to largest value. */
910 raw_exp = max_raw_exp;
911 raw_frac = max_raw_frac;
913 else if (fp->exponent >= min_norm_exp)
916 raw_frac = fp->fraction >> (64 - frac_bits);
917 raw_exp = (fp->exponent / 4) + bias;
919 else if (fp->exponent >= min_denorm_exp)
922 const int denorm_shift = min_norm_exp - fp->exponent;
923 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
928 /* Underflow to zero. */
935 /* Overflow to largest value. */
936 raw_exp = max_raw_exp;
937 raw_frac = max_raw_frac;
943 /* Treat all of these as zero, because Z architecture
944 doesn't have any reserved values. */
951 raw_exp = max_raw_exp;
952 raw_frac = max_raw_frac;
957 raw_exp = max_raw_exp;
958 raw_frac = max_raw_frac - 1;
963 raw_exp = max_raw_exp;
964 raw_frac = max_raw_frac;
971 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
972 | ((uint64_t) raw_exp << frac_bits)
976 /* Converts the neutral format floating point number in FP into a
977 null-terminated human-readable hex string in OUTPUT. */
979 assemble_hex (struct fp *fp, void *output)
984 if (fp->sign == NEGATIVE)
990 normalize_and_round_fp (fp, 64);
991 normalize_hex_fp (fp);
992 assert (fp->fraction != 0);
995 while (fp->fraction != 0)
997 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1000 if (fp->exponent != 0)
1001 sprintf (s, "p%d", fp->exponent);
1005 strcpy (s, "Infinity");
1009 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1017 strcpy (buffer, "Missing");
1021 strcpy (buffer, "Lowest");
1025 strcpy (buffer, "Highest");
1029 strcpy (s, "Reserved");
1033 strncpy (output, buffer, float_get_size (FLOAT_HEX));