1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006 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>
25 #include <libpspp/assertion.h>
26 #include <libpspp/integer-format.h>
27 #include <libpspp/str.h>
32 /* Neutral intermediate representation for binary floating-point numbers. */
37 FINITE, /* Finite number (normalized or denormalized). */
38 INFINITE, /* Positive or negative infinity. */
39 NAN, /* Not a number. */
41 ZERO, /* Positive or negative zero. */
42 MISSING, /* System missing. */
43 LOWEST, /* LOWEST on e.g. missing values. */
44 HIGHEST, /* HIGHEST on e.g. missing values. */
45 RESERVED /* Special Vax representation. */
56 /* class == FINITE: The number has value "fraction *
57 2**exponent", considering bit 63 in fraction to be just
58 right of the decimal point.
60 class == NAN: The fraction holds the significand, with its
61 leftmost bit in bit 63, so that signaling and quiet NaN
62 values can be preserved.
64 Unused for other classes. */
69 static void extract_number (enum float_format, const void *, struct fp *);
70 static void assemble_number (enum float_format, struct fp *, void *);
72 static inline uint16_t get_uint16 (const void *);
73 static inline uint32_t get_uint32 (const void *);
74 static inline uint64_t get_uint64 (const void *);
76 static inline void put_uint16 (uint16_t, void *);
77 static inline void put_uint32 (uint32_t, void *);
78 static inline void put_uint64 (uint64_t, void *);
80 /* Converts SRC from format FROM to format TO, storing the
81 converted value into DST.
82 SRC and DST are permitted to arbitrarily overlap. */
84 float_convert (enum float_format from, const void *src,
85 enum float_format to, void *dst)
89 if ((from == FLOAT_IEEE_SINGLE_LE || from == FLOAT_IEEE_SINGLE_BE)
90 && (to == FLOAT_IEEE_SINGLE_LE || to == FLOAT_IEEE_SINGLE_BE))
91 put_uint32 (bswap_32 (get_uint32 (src)), dst);
92 else if ((from == FLOAT_IEEE_DOUBLE_LE || from == FLOAT_IEEE_DOUBLE_BE)
93 && (to == FLOAT_IEEE_DOUBLE_LE || to == FLOAT_IEEE_DOUBLE_BE))
94 put_uint64 (bswap_64 (get_uint64 (src)), dst);
98 extract_number (from, src, &fp);
99 assemble_number (to, &fp, dst);
105 memmove (dst, src, float_get_size (from));
109 /* Returns the number of bytes in a number in the given
112 float_get_size (enum float_format format)
116 case FLOAT_IEEE_SINGLE_LE:
117 case FLOAT_IEEE_SINGLE_BE:
122 case FLOAT_IEEE_DOUBLE_LE:
123 case FLOAT_IEEE_DOUBLE_BE:
130 return sizeof (struct fp);
139 /* Attempts to identify the floating point format(s) in which the
140 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
141 Returns the number of matches, which may be zero, one, or
142 greater than one. If a positive value is returned, then the
143 most likely candidate format (based on how common the formats
144 are in practice) is stored in *BEST_GUESS. */
146 float_identify (double expected_value, const void *number, size_t length,
147 enum float_format *best_guess)
149 /* Candidates for identification in order of decreasing
151 enum float_format candidates[] =
153 FLOAT_IEEE_SINGLE_LE,
154 FLOAT_IEEE_SINGLE_BE,
155 FLOAT_IEEE_DOUBLE_LE,
156 FLOAT_IEEE_DOUBLE_BE,
163 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
165 enum float_format *p;
169 for (p = candidates; p < candidates + candidate_cnt; p++)
170 if (float_get_size (*p) == length)
173 assert (sizeof tmp >= float_get_size (*p));
174 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
175 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
181 /* Returns CNT bits in X starting from the given bit OFS. */
182 static inline uint64_t
183 get_bits (uint64_t x, int ofs, int cnt)
185 assert (ofs >= 0 && ofs < 64);
186 assert (cnt > 0 && cnt < 64);
187 assert (ofs + cnt <= 64);
188 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
191 /* Returns the 16-bit unsigned integer at P,
192 which need not be aligned. */
193 static inline uint16_t
194 get_uint16 (const void *p)
197 memcpy (&x, p, sizeof x);
201 /* Returns the 32-bit unsigned integer at P,
202 which need not be aligned. */
203 static inline uint32_t
204 get_uint32 (const void *p)
207 memcpy (&x, p, sizeof x);
211 /* Returns the 64-bit unsigned integer at P,
212 which need not be aligned. */
213 static inline uint64_t
214 get_uint64 (const void *p)
217 memcpy (&x, p, sizeof x);
221 /* Stores 16-bit unsigned integer X at P,
222 which need not be aligned. */
224 put_uint16 (uint16_t x, void *p)
226 memcpy (p, &x, sizeof x);
229 /* Stores 32-bit unsigned integer X at P,
230 which need not be aligned. */
232 put_uint32 (uint32_t x, void *p)
234 memcpy (p, &x, sizeof x);
237 /* Stores 64-bit unsigned integer X at P,
238 which need not be aligned. */
240 put_uint64 (uint64_t x, void *p)
242 memcpy (p, &x, sizeof x);
245 /* Returns NATIVE converted to a form that, when stored in
246 memory, will be in little-endian byte order. */
247 static inline uint16_t
248 native_to_le16 (uint16_t native)
250 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_16 (native);
253 /* Returns NATIVE converted to a form that, when stored in
254 memory, will be in big-endian byte order. */
255 static inline uint16_t
256 native_to_be16 (uint16_t native)
258 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_16 (native);
261 /* Returns NATIVE converted to a form that, when stored in
262 memory, will be in VAX-endian byte order. */
263 static inline uint16_t
264 native_to_vax16 (uint16_t native)
266 return native_to_le16 (native);
269 /* Returns NATIVE converted to a form that, when stored in
270 memory, will be in little-endian byte order. */
271 static inline uint32_t
272 native_to_le32 (uint32_t native)
274 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
277 /* Returns NATIVE converted to a form that, when stored in
278 memory, will be in big-endian byte order. */
279 static inline uint32_t
280 native_to_be32 (uint32_t native)
282 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
285 /* Returns NATIVE converted to a form that, when stored in
286 memory, will be in VAX-endian byte order. */
287 static inline uint32_t
288 native_to_vax32 (uint32_t native)
290 return native_to_be32 (((native & 0xff00ff00) >> 8) |
291 ((native & 0x00ff00ff) << 8));
294 /* Returns NATIVE converted to a form that, when stored in
295 memory, will be in little-endian byte order. */
296 static inline uint64_t
297 native_to_le64 (uint64_t native)
299 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
302 /* Returns NATIVE converted to a form that, when stored in
303 memory, will be in big-endian byte order. */
304 static inline uint64_t
305 native_to_be64 (uint64_t native)
307 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
310 /* Returns NATIVE converted to a form that, when stored in
311 memory, will be in VAX-endian byte order. */
312 static inline uint64_t
313 native_to_vax64 (uint64_t native)
315 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
316 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
317 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
318 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
321 /* Given LE, obtained from memory in little-endian format,
322 returns its value. */
323 static inline uint16_t
324 le_to_native16 (uint16_t le)
326 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_16 (le);
329 /* Given BE, obtained from memory in big-endian format, returns
331 static inline uint16_t
332 be_to_native16 (uint16_t be)
334 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_16 (be);
337 /* Given VAX, obtained from memory in VAX-endian format, returns
339 static inline uint16_t
340 vax_to_native16 (uint16_t vax)
342 return le_to_native16 (vax);
345 /* Given LE, obtained from memory in little-endian format,
346 returns its value. */
347 static inline uint32_t
348 le_to_native32 (uint32_t le)
350 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
353 /* Given BE, obtained from memory in big-endian format, returns
355 static inline uint32_t
356 be_to_native32 (uint32_t be)
358 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
361 /* Given VAX, obtained from memory in VAX-endian format, returns
363 static inline uint32_t
364 vax_to_native32 (uint32_t vax)
366 uint32_t be = be_to_native32 (vax);
367 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
370 /* Given LE, obtained from memory in little-endian format,
371 returns its value. */
372 static inline uint64_t
373 le_to_native64 (uint64_t le)
375 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
378 /* Given BE, obtained from memory in big-endian format, returns
380 static inline uint64_t
381 be_to_native64 (uint64_t be)
383 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
386 /* Given VAX, obtained from memory in VAX-endian format, returns
388 static inline uint64_t
389 vax_to_native64 (uint64_t vax)
391 uint64_t be = be_to_native64 (vax);
392 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
393 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
394 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
395 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
398 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
399 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
400 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
401 static void extract_hex (const char *, struct fp *);
403 /* Converts the number at BITS from format TYPE into neutral
406 extract_number (enum float_format type, const void *bits, struct fp *fp)
410 case FLOAT_IEEE_SINGLE_LE:
411 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
413 case FLOAT_IEEE_SINGLE_BE:
414 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
416 case FLOAT_IEEE_DOUBLE_LE:
417 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
419 case FLOAT_IEEE_DOUBLE_BE:
420 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
424 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
427 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
430 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
434 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
437 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
441 memcpy (fp, bits, sizeof *fp);
444 extract_hex (bits, fp);
448 assert (!(fp->class == FINITE && fp->fraction == 0));
451 /* Converts the IEEE format number in BITS, which has EXP_BITS of
452 exponent and FRAC_BITS of fraction, into neutral format at
455 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
457 const int bias = (1 << (exp_bits - 1)) - 1;
458 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
459 const int max_raw_exp = (1 << exp_bits) - 1;
461 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
462 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
463 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
465 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
467 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
468 fp->class = raw_sign ? MISSING : HIGHEST;
469 else if (raw_exp == max_raw_exp)
472 fp->class = INFINITE;
476 fp->fraction = raw_frac << (64 - frac_bits);
479 else if (raw_exp == 0)
484 fp->exponent = 1 - bias;
485 fp->fraction = raw_frac << (64 - frac_bits);
493 fp->exponent = raw_exp - bias + 1;
494 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
497 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
500 /* Converts the VAX format number in BITS, which has EXP_BITS of
501 exponent and FRAC_BITS of fraction, into neutral format at
504 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
506 const int bias = 1 << (exp_bits - 1);
507 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
508 const int max_raw_exp = (1 << exp_bits) - 1;
510 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
511 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
512 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
514 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
516 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
517 fp->class = raw_sign ? MISSING : HIGHEST;
518 else if (raw_exp == 0)
519 fp->class = raw_sign == 0 ? ZERO : RESERVED;
523 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
524 fp->exponent = raw_exp - bias;
527 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
530 /* Converts the Z architecture format number in BITS, which has
531 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
534 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
536 const int bias = 1 << (exp_bits - 1);
537 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
538 const int max_raw_exp = (1 << exp_bits) - 1;
540 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
541 int raw_exp = get_bits (bits, frac_bits, exp_bits);
542 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
544 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
545 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
546 fp->class = raw_sign ? MISSING : HIGHEST;
547 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
549 else if (raw_frac != 0)
552 fp->fraction = raw_frac << (64 - frac_bits);
553 fp->exponent = (raw_exp - bias) * 4;
559 /* Returns the integer value of hex digit C. */
563 const char s[] = "0123456789abcdef";
564 const char *cp = strchr (s, tolower ((unsigned char) c));
570 /* Parses a hexadecimal floating point number string at S (useful
571 for testing) into neutral format at FP. */
573 extract_hex (const char *s, struct fp *fp)
583 if (!strcmp (s, "Infinity"))
584 fp->class = INFINITE;
585 else if (!strcmp (s, "Missing"))
587 else if (!strcmp (s, "Lowest"))
589 else if (!strcmp (s, "Highest"))
591 else if (!strcmp (s, "Reserved"))
592 fp->class = RESERVED;
597 if (!memcmp (s, "NaN:", 4))
611 for (; isxdigit ((unsigned char) *s); s++)
614 uint64_t digit = hexit_value (*s);
615 fp->fraction += digit << offset;
619 if (fp->class == FINITE)
621 if (fp->fraction == 0)
626 fp->exponent += strtol (s + 1, &tail, 10);
633 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
634 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
635 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
636 static void assemble_hex (struct fp *, void *);
638 /* Converts the neutral format floating point number in FP into
639 format TYPE at NUMBER. May modify FP as part of the
642 assemble_number (enum float_format type, struct fp *fp, void *number)
646 case FLOAT_IEEE_SINGLE_LE:
647 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
649 case FLOAT_IEEE_SINGLE_BE:
650 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
652 case FLOAT_IEEE_DOUBLE_LE:
653 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
655 case FLOAT_IEEE_DOUBLE_BE:
656 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
660 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
663 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
666 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
670 put_uint64 (native_to_be32 (assemble_z (fp, 7, 24)), number);
673 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
677 memcpy (number, fp, sizeof *fp);
680 assemble_hex (fp, number);
685 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
686 Halfway values are rounded to even. */
688 normalize_and_round_fp (struct fp *fp, int frac_bits)
690 assert (fp->class == FINITE);
691 assert (fp->fraction != 0);
693 /* Make sure that the leading fraction bit is 1. */
694 while (!(fp->fraction & (UINT64_C(1) << 63)))
702 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
703 uint64_t decision_bit = last_frac_bit >> 1;
704 if (fp->fraction & decision_bit
705 && (fp->fraction & (decision_bit - 1)
706 || fp->fraction & last_frac_bit))
708 fp->fraction += last_frac_bit;
709 if ((fp->fraction >> 63) == 0)
711 fp->fraction = UINT64_C(1) << 63;
716 /* Mask off all but FRAC_BITS high-order bits.
717 If we rounded up, then these bits no longer have
718 meaningful values. */
719 fp->fraction &= ~(last_frac_bit - 1);
723 /* Converts the neutral format floating point number in FP into
724 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
725 bits, and returns the value. */
727 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
729 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
731 const int bias = (1 << (exp_bits - 1)) - 1;
732 const int max_raw_exp = (1 << exp_bits) - 1;
733 const int min_norm_exp = 1 - bias;
734 const int min_denorm_exp = min_norm_exp - frac_bits;
735 const int max_norm_exp = max_raw_exp - 1 - bias;
741 raw_sign = fp->sign != POSITIVE;
746 normalize_and_round_fp (fp, frac_bits + 1);
747 if (fp->exponent - 1 > max_norm_exp)
749 /* Overflow to infinity. */
750 raw_exp = max_raw_exp;
753 else if (fp->exponent - 1 >= min_norm_exp)
756 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
757 raw_exp = (fp->exponent - 1) + bias;
759 else if (fp->exponent - 1 >= min_denorm_exp)
762 const int denorm_shift = min_norm_exp - fp->exponent;
763 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
768 /* Underflow to zero. */
776 raw_exp = max_raw_exp;
780 raw_frac = fp->fraction >> (64 - frac_bits);
783 raw_exp = max_raw_exp;
793 raw_exp = max_raw_exp - 1;
794 raw_frac = max_raw_frac;
799 raw_exp = max_raw_exp - 1;
800 raw_frac = max_raw_frac - 1;
805 raw_exp = max_raw_exp - 1;
806 raw_frac = max_raw_frac;
810 /* Convert to what processors commonly treat as signaling NAN. */
811 raw_frac = (UINT64_C(1) << frac_bits) - 1;
812 raw_exp = max_raw_exp;
819 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
820 | ((uint64_t) raw_exp << frac_bits)
824 /* Converts the neutral format floating point number in FP into
825 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
826 bits, and returns the value. */
828 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
830 const int max_raw_exp = (1 << exp_bits) - 1;
831 const int bias = 1 << (exp_bits - 1);
832 const int min_finite_exp = 1 - bias;
833 const int max_finite_exp = max_raw_exp - bias;
834 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
840 raw_sign = fp->sign != POSITIVE;
845 normalize_and_round_fp (fp, frac_bits + 1);
846 if (fp->exponent > max_finite_exp)
848 /* Overflow to reserved operand. */
853 else if (fp->exponent >= min_finite_exp)
856 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
857 raw_exp = fp->exponent + bias;
861 /* Underflow to zero. */
884 raw_exp = max_finite_exp + bias;
885 raw_frac = max_raw_frac;
890 raw_exp = max_finite_exp + bias;
891 raw_frac = max_raw_frac - 1;
896 raw_exp = max_finite_exp + bias;
897 raw_frac = max_raw_frac;
904 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
905 | ((uint64_t) raw_exp << frac_bits)
909 /* Shift right until the exponent is a multiple of 4.
910 Rounding is not needed, because none of the formats we support
911 has more than 53 bits of precision. That is, we never shift a
912 1-bit off the right end of the fraction. */
914 normalize_hex_fp (struct fp *fp)
916 while (fp->exponent % 4)
923 /* Converts the neutral format floating point number in FP into Z
924 architecture format with EXP_BITS exponent bits and FRAC_BITS
925 fraction bits, and returns the value. */
927 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
929 const int max_raw_exp = (1 << exp_bits) - 1;
930 const int bias = 1 << (exp_bits - 1);
931 const int max_norm_exp = (max_raw_exp - bias) * 4;
932 const int min_norm_exp = -bias * 4;
933 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
935 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
941 raw_sign = fp->sign != POSITIVE;
946 normalize_and_round_fp (fp, frac_bits);
947 normalize_hex_fp (fp);
948 if (fp->exponent > max_norm_exp)
950 /* Overflow to largest value. */
951 raw_exp = max_raw_exp;
952 raw_frac = max_raw_frac;
954 else if (fp->exponent >= min_norm_exp)
957 raw_frac = fp->fraction >> (64 - frac_bits);
958 raw_exp = (fp->exponent / 4) + bias;
960 else if (fp->exponent >= min_denorm_exp)
963 const int denorm_shift = min_norm_exp - fp->exponent;
964 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
969 /* Underflow to zero. */
976 /* Overflow to largest value. */
977 raw_exp = max_raw_exp;
978 raw_frac = max_raw_frac;
984 /* Treat all of these as zero, because Z architecture
985 doesn't have any reserved values. */
992 raw_exp = max_raw_exp;
993 raw_frac = max_raw_frac;
998 raw_exp = max_raw_exp;
999 raw_frac = max_raw_frac - 1;
1004 raw_exp = max_raw_exp;
1005 raw_frac = max_raw_frac;
1012 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
1013 | ((uint64_t) raw_exp << frac_bits)
1017 /* Converts the neutral format floating point number in FP into a
1018 null-terminated human-readable hex string in OUTPUT. */
1020 assemble_hex (struct fp *fp, void *output)
1025 if (fp->sign == NEGATIVE)
1031 normalize_and_round_fp (fp, 64);
1032 normalize_hex_fp (fp);
1033 assert (fp->fraction != 0);
1036 while (fp->fraction != 0)
1038 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1041 if (fp->exponent != 0)
1042 sprintf (s, "p%d", fp->exponent);
1046 strcpy (s, "Infinity");
1050 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1058 strcpy (buffer, "Missing");
1062 strcpy (buffer, "Lowest");
1066 strcpy (buffer, "Highest");
1070 strcpy (s, "Reserved");
1074 strncpy (output, buffer, float_get_size (FLOAT_HEX));