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 uint16_t get_uint16 (const void *);
72 static inline uint32_t get_uint32 (const void *);
73 static inline uint64_t get_uint64 (const void *);
75 static inline void put_uint16 (uint16_t, void *);
76 static inline void put_uint32 (uint32_t, void *);
77 static inline void put_uint64 (uint64_t, void *);
79 /* Converts SRC from format FROM to format TO, storing the
80 converted value into DST.
81 SRC and DST are permitted to arbitrarily overlap. */
83 float_convert (enum float_format from, const void *src,
84 enum float_format to, void *dst)
88 if ((from == FLOAT_IEEE_SINGLE_LE || from == FLOAT_IEEE_SINGLE_BE)
89 && (to == FLOAT_IEEE_SINGLE_LE || to == FLOAT_IEEE_SINGLE_BE))
90 put_uint32 (bswap_32 (get_uint32 (src)), dst);
91 else if ((from == FLOAT_IEEE_DOUBLE_LE || from == FLOAT_IEEE_DOUBLE_BE)
92 && (to == FLOAT_IEEE_DOUBLE_LE || to == FLOAT_IEEE_DOUBLE_BE))
93 put_uint64 (bswap_64 (get_uint64 (src)), dst);
97 extract_number (from, src, &fp);
98 assemble_number (to, &fp, dst);
104 memmove (dst, src, float_get_size (from));
108 /* Converts SRC from format FROM to a native double and returns
111 float_get_double (enum float_format from, const void *src)
114 float_convert (from, src, FLOAT_NATIVE_DOUBLE, &dst);
118 /* Returns the number of bytes in a number in the given
121 float_get_size (enum float_format format)
125 case FLOAT_IEEE_SINGLE_LE:
126 case FLOAT_IEEE_SINGLE_BE:
131 case FLOAT_IEEE_DOUBLE_LE:
132 case FLOAT_IEEE_DOUBLE_BE:
139 return sizeof (struct fp);
148 /* Attempts to identify the floating point format(s) in which the
149 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
150 Returns the number of matches, which may be zero, one, or
151 greater than one. If a positive value is returned, then the
152 most likely candidate format (based on how common the formats
153 are in practice) is stored in *BEST_GUESS. */
155 float_identify (double expected_value, const void *number, size_t length,
156 enum float_format *best_guess)
158 /* Candidates for identification in order of decreasing
160 enum float_format candidates[] =
162 FLOAT_IEEE_SINGLE_LE,
163 FLOAT_IEEE_SINGLE_BE,
164 FLOAT_IEEE_DOUBLE_LE,
165 FLOAT_IEEE_DOUBLE_BE,
172 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
174 enum float_format *p;
178 for (p = candidates; p < candidates + candidate_cnt; p++)
179 if (float_get_size (*p) == length)
182 assert (sizeof tmp >= float_get_size (*p));
183 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
184 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
190 /* Returns the double value that is just greater than -DBL_MAX,
191 which in PSPP syntax files is called LOWEST and used as the
192 low end of numeric ranges that are supposed to be unbounded on
193 the low end, as in the missing value set created by,
194 e.g. MISSING VALUES X(LOWEST THRU 5). (-DBL_MAX is used for
195 SYSMIS so it is not available for LOWEST.) */
197 float_get_lowest (void)
204 assemble_number (FLOAT_NATIVE_DOUBLE, &fp, &x);
208 /* Returns CNT bits in X starting from the given bit OFS. */
209 static inline uint64_t
210 get_bits (uint64_t x, int ofs, int cnt)
212 assert (ofs >= 0 && ofs < 64);
213 assert (cnt > 0 && cnt < 64);
214 assert (ofs + cnt <= 64);
215 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
218 /* Returns the 16-bit unsigned integer at P,
219 which need not be aligned. */
220 static inline uint16_t
221 get_uint16 (const void *p)
224 memcpy (&x, p, sizeof x);
228 /* Returns the 32-bit unsigned integer at P,
229 which need not be aligned. */
230 static inline uint32_t
231 get_uint32 (const void *p)
234 memcpy (&x, p, sizeof x);
238 /* Returns the 64-bit unsigned integer at P,
239 which need not be aligned. */
240 static inline uint64_t
241 get_uint64 (const void *p)
244 memcpy (&x, p, sizeof x);
248 /* Stores 16-bit unsigned integer X at P,
249 which need not be aligned. */
251 put_uint16 (uint16_t x, void *p)
253 memcpy (p, &x, sizeof x);
256 /* Stores 32-bit unsigned integer X at P,
257 which need not be aligned. */
259 put_uint32 (uint32_t x, void *p)
261 memcpy (p, &x, sizeof x);
264 /* Stores 64-bit unsigned integer X at P,
265 which need not be aligned. */
267 put_uint64 (uint64_t x, void *p)
269 memcpy (p, &x, sizeof x);
272 /* Returns NATIVE converted to a form that, when stored in
273 memory, will be in little-endian byte order. */
274 static inline uint16_t
275 native_to_le16 (uint16_t native)
277 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_16 (native);
280 /* Returns NATIVE converted to a form that, when stored in
281 memory, will be in big-endian byte order. */
282 static inline uint16_t
283 native_to_be16 (uint16_t native)
285 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_16 (native);
288 /* Returns NATIVE converted to a form that, when stored in
289 memory, will be in VAX-endian byte order. */
290 static inline uint16_t
291 native_to_vax16 (uint16_t native)
293 return native_to_le16 (native);
296 /* Returns NATIVE converted to a form that, when stored in
297 memory, will be in little-endian byte order. */
298 static inline uint32_t
299 native_to_le32 (uint32_t native)
301 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
304 /* Returns NATIVE converted to a form that, when stored in
305 memory, will be in big-endian byte order. */
306 static inline uint32_t
307 native_to_be32 (uint32_t native)
309 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
312 /* Returns NATIVE converted to a form that, when stored in
313 memory, will be in VAX-endian byte order. */
314 static inline uint32_t
315 native_to_vax32 (uint32_t native)
317 return native_to_be32 (((native & 0xff00ff00) >> 8) |
318 ((native & 0x00ff00ff) << 8));
321 /* Returns NATIVE converted to a form that, when stored in
322 memory, will be in little-endian byte order. */
323 static inline uint64_t
324 native_to_le64 (uint64_t native)
326 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
329 /* Returns NATIVE converted to a form that, when stored in
330 memory, will be in big-endian byte order. */
331 static inline uint64_t
332 native_to_be64 (uint64_t native)
334 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
337 /* Returns NATIVE converted to a form that, when stored in
338 memory, will be in VAX-endian byte order. */
339 static inline uint64_t
340 native_to_vax64 (uint64_t native)
342 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
343 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
344 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
345 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
348 /* Given LE, obtained from memory in little-endian format,
349 returns its value. */
350 static inline uint16_t
351 le_to_native16 (uint16_t le)
353 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_16 (le);
356 /* Given BE, obtained from memory in big-endian format, returns
358 static inline uint16_t
359 be_to_native16 (uint16_t be)
361 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_16 (be);
364 /* Given VAX, obtained from memory in VAX-endian format, returns
366 static inline uint16_t
367 vax_to_native16 (uint16_t vax)
369 return le_to_native16 (vax);
372 /* Given LE, obtained from memory in little-endian format,
373 returns its value. */
374 static inline uint32_t
375 le_to_native32 (uint32_t le)
377 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
380 /* Given BE, obtained from memory in big-endian format, returns
382 static inline uint32_t
383 be_to_native32 (uint32_t be)
385 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
388 /* Given VAX, obtained from memory in VAX-endian format, returns
390 static inline uint32_t
391 vax_to_native32 (uint32_t vax)
393 uint32_t be = be_to_native32 (vax);
394 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
397 /* Given LE, obtained from memory in little-endian format,
398 returns its value. */
399 static inline uint64_t
400 le_to_native64 (uint64_t le)
402 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
405 /* Given BE, obtained from memory in big-endian format, returns
407 static inline uint64_t
408 be_to_native64 (uint64_t be)
410 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
413 /* Given VAX, obtained from memory in VAX-endian format, returns
415 static inline uint64_t
416 vax_to_native64 (uint64_t vax)
418 uint64_t be = be_to_native64 (vax);
419 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
420 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
421 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
422 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
425 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
426 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
427 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
428 static void extract_hex (const char *, struct fp *);
430 /* Converts the number at BITS from format TYPE into neutral
433 extract_number (enum float_format type, const void *bits, struct fp *fp)
437 case FLOAT_IEEE_SINGLE_LE:
438 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
440 case FLOAT_IEEE_SINGLE_BE:
441 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
443 case FLOAT_IEEE_DOUBLE_LE:
444 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
446 case FLOAT_IEEE_DOUBLE_BE:
447 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
451 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
454 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
457 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
461 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
464 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
468 memcpy (fp, bits, sizeof *fp);
471 extract_hex (bits, fp);
475 assert (!(fp->class == FINITE && fp->fraction == 0));
478 /* Converts the IEEE format number in BITS, which has EXP_BITS of
479 exponent and FRAC_BITS of fraction, into neutral format at
482 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
484 const int bias = (1 << (exp_bits - 1)) - 1;
485 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
486 const int max_raw_exp = (1 << exp_bits) - 1;
488 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
489 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
490 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
492 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
494 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
495 fp->class = raw_sign ? MISSING : HIGHEST;
496 else if (raw_exp == max_raw_exp)
499 fp->class = INFINITE;
503 fp->fraction = raw_frac << (64 - frac_bits);
506 else if (raw_exp == 0)
511 fp->exponent = 1 - bias;
512 fp->fraction = raw_frac << (64 - frac_bits);
520 fp->exponent = raw_exp - bias + 1;
521 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
524 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
527 /* Converts the VAX format number in BITS, which has EXP_BITS of
528 exponent and FRAC_BITS of fraction, into neutral format at
531 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
533 const int bias = 1 << (exp_bits - 1);
534 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
535 const int max_raw_exp = (1 << exp_bits) - 1;
537 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
538 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
539 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
541 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
543 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
544 fp->class = raw_sign ? MISSING : HIGHEST;
545 else if (raw_exp == 0)
546 fp->class = raw_sign == 0 ? ZERO : RESERVED;
550 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
551 fp->exponent = raw_exp - bias;
554 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
557 /* Converts the Z architecture format number in BITS, which has
558 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
561 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
563 const int bias = 1 << (exp_bits - 1);
564 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
565 const int max_raw_exp = (1 << exp_bits) - 1;
567 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
568 int raw_exp = get_bits (bits, frac_bits, exp_bits);
569 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
571 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
572 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
573 fp->class = raw_sign ? MISSING : HIGHEST;
574 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
576 else if (raw_frac != 0)
579 fp->fraction = raw_frac << (64 - frac_bits);
580 fp->exponent = (raw_exp - bias) * 4;
586 /* Returns the integer value of hex digit C. */
590 const char s[] = "0123456789abcdef";
591 const char *cp = strchr (s, tolower ((unsigned char) c));
597 /* Parses a hexadecimal floating point number string at S (useful
598 for testing) into neutral format at FP. */
600 extract_hex (const char *s, struct fp *fp)
610 if (!strcmp (s, "Infinity"))
611 fp->class = INFINITE;
612 else if (!strcmp (s, "Missing"))
614 else if (!strcmp (s, "Lowest"))
616 else if (!strcmp (s, "Highest"))
618 else if (!strcmp (s, "Reserved"))
619 fp->class = RESERVED;
624 if (!memcmp (s, "NaN:", 4))
638 for (; isxdigit ((unsigned char) *s); s++)
641 uint64_t digit = hexit_value (*s);
642 fp->fraction += digit << offset;
646 if (fp->class == FINITE)
648 if (fp->fraction == 0)
653 fp->exponent += strtol (s + 1, &tail, 10);
660 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
661 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
662 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
663 static void assemble_hex (struct fp *, void *);
665 /* Converts the neutral format floating point number in FP into
666 format TYPE at NUMBER. May modify FP as part of the
669 assemble_number (enum float_format type, struct fp *fp, void *number)
673 case FLOAT_IEEE_SINGLE_LE:
674 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
676 case FLOAT_IEEE_SINGLE_BE:
677 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
679 case FLOAT_IEEE_DOUBLE_LE:
680 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
682 case FLOAT_IEEE_DOUBLE_BE:
683 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
687 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
690 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
693 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
697 put_uint32 (native_to_be32 (assemble_z (fp, 7, 24)), number);
700 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
704 memcpy (number, fp, sizeof *fp);
707 assemble_hex (fp, number);
712 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
713 Halfway values are rounded to even. */
715 normalize_and_round_fp (struct fp *fp, int frac_bits)
717 assert (fp->class == FINITE);
718 assert (fp->fraction != 0);
720 /* Make sure that the leading fraction bit is 1. */
721 while (!(fp->fraction & (UINT64_C(1) << 63)))
729 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
730 uint64_t decision_bit = last_frac_bit >> 1;
731 if (fp->fraction & decision_bit
732 && (fp->fraction & (decision_bit - 1)
733 || fp->fraction & last_frac_bit))
735 fp->fraction += last_frac_bit;
736 if ((fp->fraction >> 63) == 0)
738 fp->fraction = UINT64_C(1) << 63;
743 /* Mask off all but FRAC_BITS high-order bits.
744 If we rounded up, then these bits no longer have
745 meaningful values. */
746 fp->fraction &= ~(last_frac_bit - 1);
750 /* Converts the neutral format floating point number in FP into
751 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
752 bits, and returns the value. */
754 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
756 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
758 const int bias = (1 << (exp_bits - 1)) - 1;
759 const int max_raw_exp = (1 << exp_bits) - 1;
760 const int min_norm_exp = 1 - bias;
761 const int min_denorm_exp = min_norm_exp - frac_bits;
762 const int max_norm_exp = max_raw_exp - 1 - bias;
768 raw_sign = fp->sign != POSITIVE;
773 normalize_and_round_fp (fp, frac_bits + 1);
774 if (fp->exponent - 1 > max_norm_exp)
776 /* Overflow to infinity. */
777 raw_exp = max_raw_exp;
780 else if (fp->exponent - 1 >= min_norm_exp)
783 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
784 raw_exp = (fp->exponent - 1) + bias;
786 else if (fp->exponent - 1 >= min_denorm_exp)
789 const int denorm_shift = min_norm_exp - fp->exponent;
790 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
795 /* Underflow to zero. */
803 raw_exp = max_raw_exp;
807 raw_frac = fp->fraction >> (64 - frac_bits);
810 raw_exp = max_raw_exp;
820 raw_exp = max_raw_exp - 1;
821 raw_frac = max_raw_frac;
826 raw_exp = max_raw_exp - 1;
827 raw_frac = max_raw_frac - 1;
832 raw_exp = max_raw_exp - 1;
833 raw_frac = max_raw_frac;
837 /* Convert to what processors commonly treat as signaling NAN. */
838 raw_frac = (UINT64_C(1) << frac_bits) - 1;
839 raw_exp = max_raw_exp;
846 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
847 | ((uint64_t) raw_exp << frac_bits)
851 /* Converts the neutral format floating point number in FP into
852 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
853 bits, and returns the value. */
855 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
857 const int max_raw_exp = (1 << exp_bits) - 1;
858 const int bias = 1 << (exp_bits - 1);
859 const int min_finite_exp = 1 - bias;
860 const int max_finite_exp = max_raw_exp - bias;
861 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
867 raw_sign = fp->sign != POSITIVE;
872 normalize_and_round_fp (fp, frac_bits + 1);
873 if (fp->exponent > max_finite_exp)
875 /* Overflow to reserved operand. */
880 else if (fp->exponent >= min_finite_exp)
883 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
884 raw_exp = fp->exponent + bias;
888 /* Underflow to zero. */
911 raw_exp = max_finite_exp + bias;
912 raw_frac = max_raw_frac;
917 raw_exp = max_finite_exp + bias;
918 raw_frac = max_raw_frac - 1;
923 raw_exp = max_finite_exp + bias;
924 raw_frac = max_raw_frac;
931 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
932 | ((uint64_t) raw_exp << frac_bits)
936 /* Shift right until the exponent is a multiple of 4.
937 Rounding is not needed, because none of the formats we support
938 has more than 53 bits of precision. That is, we never shift a
939 1-bit off the right end of the fraction. */
941 normalize_hex_fp (struct fp *fp)
943 while (fp->exponent % 4)
950 /* Converts the neutral format floating point number in FP into Z
951 architecture format with EXP_BITS exponent bits and FRAC_BITS
952 fraction bits, and returns the value. */
954 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
956 const int max_raw_exp = (1 << exp_bits) - 1;
957 const int bias = 1 << (exp_bits - 1);
958 const int max_norm_exp = (max_raw_exp - bias) * 4;
959 const int min_norm_exp = -bias * 4;
960 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
962 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
968 raw_sign = fp->sign != POSITIVE;
973 normalize_and_round_fp (fp, frac_bits);
974 normalize_hex_fp (fp);
975 if (fp->exponent > max_norm_exp)
977 /* Overflow to largest value. */
978 raw_exp = max_raw_exp;
979 raw_frac = max_raw_frac;
981 else if (fp->exponent >= min_norm_exp)
984 raw_frac = fp->fraction >> (64 - frac_bits);
985 raw_exp = (fp->exponent / 4) + bias;
987 else if (fp->exponent >= min_denorm_exp)
990 const int denorm_shift = min_norm_exp - fp->exponent;
991 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
996 /* Underflow to zero. */
1003 /* Overflow to largest value. */
1004 raw_exp = max_raw_exp;
1005 raw_frac = max_raw_frac;
1011 /* Treat all of these as zero, because Z architecture
1012 doesn't have any reserved values. */
1019 raw_exp = max_raw_exp;
1020 raw_frac = max_raw_frac;
1025 raw_exp = max_raw_exp;
1026 raw_frac = max_raw_frac - 1;
1031 raw_exp = max_raw_exp;
1032 raw_frac = max_raw_frac;
1039 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
1040 | ((uint64_t) raw_exp << frac_bits)
1044 /* Converts the neutral format floating point number in FP into a
1045 null-terminated human-readable hex string in OUTPUT. */
1047 assemble_hex (struct fp *fp, void *output)
1052 if (fp->sign == NEGATIVE)
1058 normalize_and_round_fp (fp, 64);
1059 normalize_hex_fp (fp);
1060 assert (fp->fraction != 0);
1063 while (fp->fraction != 0)
1065 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1068 if (fp->exponent != 0)
1069 sprintf (s, "p%d", fp->exponent);
1073 strcpy (s, "Infinity");
1077 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1085 strcpy (buffer, "Missing");
1089 strcpy (buffer, "Lowest");
1093 strcpy (buffer, "Highest");
1097 strcpy (s, "Reserved");
1101 strncpy (output, buffer, float_get_size (FLOAT_HEX));