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"
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 /* Converts SRC from format FROM to a native double and returns
112 float_get_double (enum float_format from, const void *src)
115 float_convert (from, src, FLOAT_NATIVE_DOUBLE, &dst);
119 /* Returns the number of bytes in a number in the given
122 float_get_size (enum float_format format)
126 case FLOAT_IEEE_SINGLE_LE:
127 case FLOAT_IEEE_SINGLE_BE:
132 case FLOAT_IEEE_DOUBLE_LE:
133 case FLOAT_IEEE_DOUBLE_BE:
140 return sizeof (struct fp);
149 /* Attempts to identify the floating point format(s) in which the
150 LENGTH bytes in NUMBER represent the given EXPECTED_VALUE.
151 Returns the number of matches, which may be zero, one, or
152 greater than one. If a positive value is returned, then the
153 most likely candidate format (based on how common the formats
154 are in practice) is stored in *BEST_GUESS. */
156 float_identify (double expected_value, const void *number, size_t length,
157 enum float_format *best_guess)
159 /* Candidates for identification in order of decreasing
161 enum float_format candidates[] =
163 FLOAT_IEEE_SINGLE_LE,
164 FLOAT_IEEE_SINGLE_BE,
165 FLOAT_IEEE_DOUBLE_LE,
166 FLOAT_IEEE_DOUBLE_BE,
173 const size_t candidate_cnt = sizeof candidates / sizeof *candidates;
175 enum float_format *p;
179 for (p = candidates; p < candidates + candidate_cnt; p++)
180 if (float_get_size (*p) == length)
183 assert (sizeof tmp >= float_get_size (*p));
184 float_convert (FLOAT_NATIVE_DOUBLE, &expected_value, *p, tmp);
185 if (!memcmp (tmp, number, length) && match_cnt++ == 0)
191 /* Returns the double value that is just greater than -DBL_MAX,
192 which in PSPP syntax files is called LOWEST and used as the
193 low end of numeric ranges that are supposed to be unbounded on
194 the low end, as in the missing value set created by,
195 e.g. MISSING VALUES X(LOWEST THRU 5). (-DBL_MAX is used for
196 SYSMIS so it is not available for LOWEST.) */
198 float_get_lowest (void)
205 assemble_number (FLOAT_NATIVE_DOUBLE, &fp, &x);
209 /* Returns CNT bits in X starting from the given bit OFS. */
210 static inline uint64_t
211 get_bits (uint64_t x, int ofs, int cnt)
213 assert (ofs >= 0 && ofs < 64);
214 assert (cnt > 0 && cnt < 64);
215 assert (ofs + cnt <= 64);
216 return (x >> ofs) & ((UINT64_C(1) << cnt) - 1);
219 /* Returns the 16-bit unsigned integer at P,
220 which need not be aligned. */
221 static inline uint16_t
222 get_uint16 (const void *p)
225 memcpy (&x, p, sizeof x);
229 /* Returns the 32-bit unsigned integer at P,
230 which need not be aligned. */
231 static inline uint32_t
232 get_uint32 (const void *p)
235 memcpy (&x, p, sizeof x);
239 /* Returns the 64-bit unsigned integer at P,
240 which need not be aligned. */
241 static inline uint64_t
242 get_uint64 (const void *p)
245 memcpy (&x, p, sizeof x);
249 /* Stores 16-bit unsigned integer X at P,
250 which need not be aligned. */
252 put_uint16 (uint16_t x, void *p)
254 memcpy (p, &x, sizeof x);
257 /* Stores 32-bit unsigned integer X at P,
258 which need not be aligned. */
260 put_uint32 (uint32_t x, void *p)
262 memcpy (p, &x, sizeof x);
265 /* Stores 64-bit unsigned integer X at P,
266 which need not be aligned. */
268 put_uint64 (uint64_t x, void *p)
270 memcpy (p, &x, sizeof x);
273 /* Returns NATIVE converted to a form that, when stored in
274 memory, will be in little-endian byte order. */
275 static inline uint16_t
276 native_to_le16 (uint16_t native)
278 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_16 (native);
281 /* Returns NATIVE converted to a form that, when stored in
282 memory, will be in big-endian byte order. */
283 static inline uint16_t
284 native_to_be16 (uint16_t native)
286 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_16 (native);
289 /* Returns NATIVE converted to a form that, when stored in
290 memory, will be in VAX-endian byte order. */
291 static inline uint16_t
292 native_to_vax16 (uint16_t native)
294 return native_to_le16 (native);
297 /* Returns NATIVE converted to a form that, when stored in
298 memory, will be in little-endian byte order. */
299 static inline uint32_t
300 native_to_le32 (uint32_t native)
302 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_32 (native);
305 /* Returns NATIVE converted to a form that, when stored in
306 memory, will be in big-endian byte order. */
307 static inline uint32_t
308 native_to_be32 (uint32_t native)
310 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_32 (native);
313 /* Returns NATIVE converted to a form that, when stored in
314 memory, will be in VAX-endian byte order. */
315 static inline uint32_t
316 native_to_vax32 (uint32_t native)
318 return native_to_be32 (((native & 0xff00ff00) >> 8) |
319 ((native & 0x00ff00ff) << 8));
322 /* Returns NATIVE converted to a form that, when stored in
323 memory, will be in little-endian byte order. */
324 static inline uint64_t
325 native_to_le64 (uint64_t native)
327 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? native : bswap_64 (native);
330 /* Returns NATIVE converted to a form that, when stored in
331 memory, will be in big-endian byte order. */
332 static inline uint64_t
333 native_to_be64 (uint64_t native)
335 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? native : bswap_64 (native);
338 /* Returns NATIVE converted to a form that, when stored in
339 memory, will be in VAX-endian byte order. */
340 static inline uint64_t
341 native_to_vax64 (uint64_t native)
343 return native_to_be64 (((native & UINT64_C(0xff00ff0000000000)) >> 40) |
344 ((native & UINT64_C(0x00ff00ff00000000)) >> 24) |
345 ((native & UINT64_C(0x00000000ff00ff00)) << 24) |
346 ((native & UINT64_C(0x0000000000ff00ff)) << 40));
349 /* Given LE, obtained from memory in little-endian format,
350 returns its value. */
351 static inline uint16_t
352 le_to_native16 (uint16_t le)
354 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_16 (le);
357 /* Given BE, obtained from memory in big-endian format, returns
359 static inline uint16_t
360 be_to_native16 (uint16_t be)
362 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_16 (be);
365 /* Given VAX, obtained from memory in VAX-endian format, returns
367 static inline uint16_t
368 vax_to_native16 (uint16_t vax)
370 return le_to_native16 (vax);
373 /* Given LE, obtained from memory in little-endian format,
374 returns its value. */
375 static inline uint32_t
376 le_to_native32 (uint32_t le)
378 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_32 (le);
381 /* Given BE, obtained from memory in big-endian format, returns
383 static inline uint32_t
384 be_to_native32 (uint32_t be)
386 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_32 (be);
389 /* Given VAX, obtained from memory in VAX-endian format, returns
391 static inline uint32_t
392 vax_to_native32 (uint32_t vax)
394 uint32_t be = be_to_native32 (vax);
395 return ((be & 0xff00ff00) >> 8) | ((be & 0x00ff00ff) << 8);
398 /* Given LE, obtained from memory in little-endian format,
399 returns its value. */
400 static inline uint64_t
401 le_to_native64 (uint64_t le)
403 return INTEGER_NATIVE == INTEGER_LSB_FIRST ? le : bswap_64 (le);
406 /* Given BE, obtained from memory in big-endian format, returns
408 static inline uint64_t
409 be_to_native64 (uint64_t be)
411 return INTEGER_NATIVE == INTEGER_MSB_FIRST ? be : bswap_64 (be);
414 /* Given VAX, obtained from memory in VAX-endian format, returns
416 static inline uint64_t
417 vax_to_native64 (uint64_t vax)
419 uint64_t be = be_to_native64 (vax);
420 return (((be & UINT64_C(0xff00ff0000000000)) >> 40) |
421 ((be & UINT64_C(0x00ff00ff00000000)) >> 24) |
422 ((be & UINT64_C(0x00000000ff00ff00)) << 24) |
423 ((be & UINT64_C(0x0000000000ff00ff)) << 40));
426 static void extract_ieee (uint64_t, int exp_bits, int frac_bits, struct fp *);
427 static void extract_vax (uint64_t, int exp_bits, int frac_bits, struct fp *);
428 static void extract_z (uint64_t, int exp_bits, int frac_bits, struct fp *);
429 static void extract_hex (const char *, struct fp *);
431 /* Converts the number at BITS from format TYPE into neutral
434 extract_number (enum float_format type, const void *bits, struct fp *fp)
438 case FLOAT_IEEE_SINGLE_LE:
439 extract_ieee (le_to_native32 (get_uint32 (bits)), 8, 23, fp);
441 case FLOAT_IEEE_SINGLE_BE:
442 extract_ieee (be_to_native32 (get_uint32 (bits)), 8, 23, fp);
444 case FLOAT_IEEE_DOUBLE_LE:
445 extract_ieee (le_to_native64 (get_uint64 (bits)), 11, 52, fp);
447 case FLOAT_IEEE_DOUBLE_BE:
448 extract_ieee (be_to_native64 (get_uint64 (bits)), 11, 52, fp);
452 extract_vax (vax_to_native32 (get_uint32 (bits)), 8, 23, fp);
455 extract_vax (vax_to_native64 (get_uint64 (bits)), 8, 55, fp);
458 extract_vax (vax_to_native64 (get_uint64 (bits)), 11, 52, fp);
462 extract_z (be_to_native32 (get_uint32 (bits)), 7, 24, fp);
465 extract_z (be_to_native64 (get_uint64 (bits)), 7, 56, fp);
469 memcpy (fp, bits, sizeof *fp);
472 extract_hex (bits, fp);
476 assert (!(fp->class == FINITE && fp->fraction == 0));
479 /* Converts the IEEE format number in BITS, which has EXP_BITS of
480 exponent and FRAC_BITS of fraction, into neutral format at
483 extract_ieee (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
485 const int bias = (1 << (exp_bits - 1)) - 1;
486 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
487 const int max_raw_exp = (1 << exp_bits) - 1;
489 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
490 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
491 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
493 if (raw_sign && raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac - 1)
495 else if (raw_exp == max_raw_exp - 1 && raw_frac == max_raw_frac)
496 fp->class = raw_sign ? MISSING : HIGHEST;
497 else if (raw_exp == max_raw_exp)
500 fp->class = INFINITE;
504 fp->fraction = raw_frac << (64 - frac_bits);
507 else if (raw_exp == 0)
512 fp->exponent = 1 - bias;
513 fp->fraction = raw_frac << (64 - frac_bits);
521 fp->exponent = raw_exp - bias + 1;
522 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
525 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
528 /* Converts the VAX format number in BITS, which has EXP_BITS of
529 exponent and FRAC_BITS of fraction, into neutral format at
532 extract_vax (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
534 const int bias = 1 << (exp_bits - 1);
535 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
536 const int max_raw_exp = (1 << exp_bits) - 1;
538 const uint64_t raw_frac = get_bits (bits, 0, frac_bits);
539 const int raw_exp = get_bits (bits, frac_bits, exp_bits);
540 const bool raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
542 if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
544 else if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
545 fp->class = raw_sign ? MISSING : HIGHEST;
546 else if (raw_exp == 0)
547 fp->class = raw_sign == 0 ? ZERO : RESERVED;
551 fp->fraction = (raw_frac << (64 - frac_bits - 1)) | (UINT64_C(1) << 63);
552 fp->exponent = raw_exp - bias;
555 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
558 /* Converts the Z architecture format number in BITS, which has
559 EXP_BITS of exponent and FRAC_BITS of fraction, into neutral
562 extract_z (uint64_t bits, int exp_bits, int frac_bits, struct fp *fp)
564 const int bias = 1 << (exp_bits - 1);
565 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
566 const int max_raw_exp = (1 << exp_bits) - 1;
568 uint64_t raw_frac = get_bits (bits, 0, frac_bits);
569 int raw_exp = get_bits (bits, frac_bits, exp_bits);
570 int raw_sign = get_bits (bits, frac_bits + exp_bits, 1);
572 fp->sign = raw_sign ? NEGATIVE : POSITIVE;
573 if (raw_exp == max_raw_exp && raw_frac == max_raw_frac)
574 fp->class = raw_sign ? MISSING : HIGHEST;
575 else if (raw_sign && raw_exp == max_raw_exp && raw_frac == max_raw_frac - 1)
577 else if (raw_frac != 0)
580 fp->fraction = raw_frac << (64 - frac_bits);
581 fp->exponent = (raw_exp - bias) * 4;
587 /* Returns the integer value of hex digit C. */
591 const char s[] = "0123456789abcdef";
592 const char *cp = strchr (s, tolower ((unsigned char) c));
598 /* Parses a hexadecimal floating point number string at S (useful
599 for testing) into neutral format at FP. */
601 extract_hex (const char *s, struct fp *fp)
611 if (!strcmp (s, "Infinity"))
612 fp->class = INFINITE;
613 else if (!strcmp (s, "Missing"))
615 else if (!strcmp (s, "Lowest"))
617 else if (!strcmp (s, "Highest"))
619 else if (!strcmp (s, "Reserved"))
620 fp->class = RESERVED;
625 if (!memcmp (s, "NaN:", 4))
639 for (; isxdigit ((unsigned char) *s); s++)
642 uint64_t digit = hexit_value (*s);
643 fp->fraction += digit << offset;
647 if (fp->class == FINITE)
649 if (fp->fraction == 0)
654 fp->exponent += strtol (s + 1, &tail, 10);
661 static uint64_t assemble_ieee (struct fp *, int exp_bits, int frac_bits);
662 static uint64_t assemble_vax (struct fp *, int exp_bits, int frac_bits);
663 static uint64_t assemble_z (struct fp *, int exp_bits, int frac_bits);
664 static void assemble_hex (struct fp *, void *);
666 /* Converts the neutral format floating point number in FP into
667 format TYPE at NUMBER. May modify FP as part of the
670 assemble_number (enum float_format type, struct fp *fp, void *number)
674 case FLOAT_IEEE_SINGLE_LE:
675 put_uint32 (native_to_le32 (assemble_ieee (fp, 8, 23)), number);
677 case FLOAT_IEEE_SINGLE_BE:
678 put_uint32 (native_to_be32 (assemble_ieee (fp, 8, 23)), number);
680 case FLOAT_IEEE_DOUBLE_LE:
681 put_uint64 (native_to_le64 (assemble_ieee (fp, 11, 52)), number);
683 case FLOAT_IEEE_DOUBLE_BE:
684 put_uint64 (native_to_be64 (assemble_ieee (fp, 11, 52)), number);
688 put_uint32 (native_to_vax32 (assemble_vax (fp, 8, 23)), number);
691 put_uint64 (native_to_vax64 (assemble_vax (fp, 8, 55)), number);
694 put_uint64 (native_to_vax64 (assemble_vax (fp, 11, 52)), number);
698 put_uint32 (native_to_be32 (assemble_z (fp, 7, 24)), number);
701 put_uint64 (native_to_be64 (assemble_z (fp, 7, 56)), number);
705 memcpy (number, fp, sizeof *fp);
708 assemble_hex (fp, number);
713 /* Rounds off FP's fraction to FRAC_BITS bits of precision.
714 Halfway values are rounded to even. */
716 normalize_and_round_fp (struct fp *fp, int frac_bits)
718 assert (fp->class == FINITE);
719 assert (fp->fraction != 0);
721 /* Make sure that the leading fraction bit is 1. */
722 while (!(fp->fraction & (UINT64_C(1) << 63)))
730 uint64_t last_frac_bit = UINT64_C(1) << (64 - frac_bits);
731 uint64_t decision_bit = last_frac_bit >> 1;
732 if (fp->fraction & decision_bit
733 && (fp->fraction & (decision_bit - 1)
734 || fp->fraction & last_frac_bit))
736 fp->fraction += last_frac_bit;
737 if ((fp->fraction >> 63) == 0)
739 fp->fraction = UINT64_C(1) << 63;
744 /* Mask off all but FRAC_BITS high-order bits.
745 If we rounded up, then these bits no longer have
746 meaningful values. */
747 fp->fraction &= ~(last_frac_bit - 1);
751 /* Converts the neutral format floating point number in FP into
752 IEEE format with EXP_BITS exponent bits and FRAC_BITS fraction
753 bits, and returns the value. */
755 assemble_ieee (struct fp *fp, int exp_bits, int frac_bits)
757 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
759 const int bias = (1 << (exp_bits - 1)) - 1;
760 const int max_raw_exp = (1 << exp_bits) - 1;
761 const int min_norm_exp = 1 - bias;
762 const int min_denorm_exp = min_norm_exp - frac_bits;
763 const int max_norm_exp = max_raw_exp - 1 - bias;
769 raw_sign = fp->sign != POSITIVE;
774 normalize_and_round_fp (fp, frac_bits + 1);
775 if (fp->exponent - 1 > max_norm_exp)
777 /* Overflow to infinity. */
778 raw_exp = max_raw_exp;
781 else if (fp->exponent - 1 >= min_norm_exp)
784 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
785 raw_exp = (fp->exponent - 1) + bias;
787 else if (fp->exponent - 1 >= min_denorm_exp)
790 const int denorm_shift = min_norm_exp - fp->exponent;
791 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
796 /* Underflow to zero. */
804 raw_exp = max_raw_exp;
808 raw_frac = fp->fraction >> (64 - frac_bits);
811 raw_exp = max_raw_exp;
821 raw_exp = max_raw_exp - 1;
822 raw_frac = max_raw_frac;
827 raw_exp = max_raw_exp - 1;
828 raw_frac = max_raw_frac - 1;
833 raw_exp = max_raw_exp - 1;
834 raw_frac = max_raw_frac;
838 /* Convert to what processors commonly treat as signaling NAN. */
839 raw_frac = (UINT64_C(1) << frac_bits) - 1;
840 raw_exp = max_raw_exp;
847 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
848 | ((uint64_t) raw_exp << frac_bits)
852 /* Converts the neutral format floating point number in FP into
853 VAX format with EXP_BITS exponent bits and FRAC_BITS fraction
854 bits, and returns the value. */
856 assemble_vax (struct fp *fp, int exp_bits, int frac_bits)
858 const int max_raw_exp = (1 << exp_bits) - 1;
859 const int bias = 1 << (exp_bits - 1);
860 const int min_finite_exp = 1 - bias;
861 const int max_finite_exp = max_raw_exp - bias;
862 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
868 raw_sign = fp->sign != POSITIVE;
873 normalize_and_round_fp (fp, frac_bits + 1);
874 if (fp->exponent > max_finite_exp)
876 /* Overflow to reserved operand. */
881 else if (fp->exponent >= min_finite_exp)
884 raw_frac = (fp->fraction << 1) >> (64 - frac_bits);
885 raw_exp = fp->exponent + bias;
889 /* Underflow to zero. */
912 raw_exp = max_finite_exp + bias;
913 raw_frac = max_raw_frac;
918 raw_exp = max_finite_exp + bias;
919 raw_frac = max_raw_frac - 1;
924 raw_exp = max_finite_exp + bias;
925 raw_frac = max_raw_frac;
932 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
933 | ((uint64_t) raw_exp << frac_bits)
937 /* Shift right until the exponent is a multiple of 4.
938 Rounding is not needed, because none of the formats we support
939 has more than 53 bits of precision. That is, we never shift a
940 1-bit off the right end of the fraction. */
942 normalize_hex_fp (struct fp *fp)
944 while (fp->exponent % 4)
951 /* Converts the neutral format floating point number in FP into Z
952 architecture format with EXP_BITS exponent bits and FRAC_BITS
953 fraction bits, and returns the value. */
955 assemble_z (struct fp *fp, int exp_bits, int frac_bits)
957 const int max_raw_exp = (1 << exp_bits) - 1;
958 const int bias = 1 << (exp_bits - 1);
959 const int max_norm_exp = (max_raw_exp - bias) * 4;
960 const int min_norm_exp = -bias * 4;
961 const int min_denorm_exp = min_norm_exp - (frac_bits - 1);
963 const uint64_t max_raw_frac = (UINT64_C(1) << frac_bits) - 1;
969 raw_sign = fp->sign != POSITIVE;
974 normalize_and_round_fp (fp, frac_bits);
975 normalize_hex_fp (fp);
976 if (fp->exponent > max_norm_exp)
978 /* Overflow to largest value. */
979 raw_exp = max_raw_exp;
980 raw_frac = max_raw_frac;
982 else if (fp->exponent >= min_norm_exp)
985 raw_frac = fp->fraction >> (64 - frac_bits);
986 raw_exp = (fp->exponent / 4) + bias;
988 else if (fp->exponent >= min_denorm_exp)
991 const int denorm_shift = min_norm_exp - fp->exponent;
992 raw_frac = (fp->fraction >> (64 - frac_bits)) >> denorm_shift;
997 /* Underflow to zero. */
1004 /* Overflow to largest value. */
1005 raw_exp = max_raw_exp;
1006 raw_frac = max_raw_frac;
1012 /* Treat all of these as zero, because Z architecture
1013 doesn't have any reserved values. */
1020 raw_exp = max_raw_exp;
1021 raw_frac = max_raw_frac;
1026 raw_exp = max_raw_exp;
1027 raw_frac = max_raw_frac - 1;
1032 raw_exp = max_raw_exp;
1033 raw_frac = max_raw_frac;
1040 return (((uint64_t) raw_sign << (frac_bits + exp_bits))
1041 | ((uint64_t) raw_exp << frac_bits)
1045 /* Converts the neutral format floating point number in FP into a
1046 null-terminated human-readable hex string in OUTPUT. */
1048 assemble_hex (struct fp *fp, void *output)
1053 if (fp->sign == NEGATIVE)
1059 normalize_and_round_fp (fp, 64);
1060 normalize_hex_fp (fp);
1061 assert (fp->fraction != 0);
1064 while (fp->fraction != 0)
1066 *s++ = (fp->fraction >> 60)["0123456789abcdef"];
1069 if (fp->exponent != 0)
1070 sprintf (s, "p%d", fp->exponent);
1074 strcpy (s, "Infinity");
1078 sprintf (s, "NaN:%016"PRIx64, fp->fraction);
1086 strcpy (buffer, "Missing");
1090 strcpy (buffer, "Lowest");
1094 strcpy (buffer, "Highest");
1098 strcpy (s, "Reserved");
1102 strncpy (output, buffer, float_get_size (FLOAT_HEX));