1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2009, 2011, 2012 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 "data/data-out.h"
29 #include "data/calendar.h"
30 #include "data/format.h"
31 #include "data/settings.h"
32 #include "data/value.h"
33 #include "libpspp/assertion.h"
34 #include "libpspp/cast.h"
35 #include "libpspp/float-format.h"
36 #include "libpspp/i18n.h"
37 #include "libpspp/integer-format.h"
38 #include "libpspp/message.h"
39 #include "libpspp/misc.h"
40 #include "libpspp/pool.h"
41 #include "libpspp/str.h"
43 #include "gl/minmax.h"
46 #define _(msgid) gettext (msgid)
48 /* A representation of a number that can be quickly rounded to
49 any desired number of decimal places (up to a specified
53 char string[64]; /* Magnitude of number with excess precision. */
54 int integer_digits; /* Number of digits before decimal point. */
55 int leading_nines; /* Number of `9's or `.'s at start of string. */
56 int leading_zeros; /* Number of `0's or `.'s at start of string. */
57 bool negative; /* Is the number negative? */
60 static void rounder_init (struct rounder *, double number, int max_decimals);
61 static int rounder_width (const struct rounder *, int decimals,
62 int *integer_digits, bool *negative);
63 static void rounder_format (const struct rounder *, int decimals,
66 typedef void data_out_converter_func (const union value *,
67 const struct fmt_spec *,
69 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
70 static data_out_converter_func output_##METHOD;
73 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
74 bool require_affixes, char *);
75 static bool output_scientific (double, const struct fmt_spec *,
76 bool require_affixes, char *);
78 static double power10 (int) PURE_FUNCTION;
79 static double power256 (int) PURE_FUNCTION;
81 static void output_infinite (double, const struct fmt_spec *, char *);
82 static void output_missing (const struct fmt_spec *, char *);
83 static void output_overflow (const struct fmt_spec *, char *);
84 static bool output_bcd_integer (double, int digits, char *);
85 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
87 static void output_hex (const void *, size_t bytes, char *);
90 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
92 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
96 /* Converts the INPUT value, encoded in INPUT_ENCODING, according to format
97 specification FORMAT, appending the output to OUTPUT in OUTPUT_ENCODING.
98 However, binary formats (FMT_P, FMT_PK, FMT_IB, FMT_PIB, FMT_RB) yield the
99 binary results, which may not be properly encoded for OUTPUT_ENCODING.
101 VALUE must be the correct width for FORMAT, that is, its width must be
102 fmt_var_width(FORMAT).
104 INPUT_ENCODING can normally be obtained by calling dict_get_encoding() on
105 the dictionary with which INPUT is associated. ENCODING is only important
106 when FORMAT's type is FMT_A. */
108 data_out_recode (const union value *input, const char *input_encoding,
109 const struct fmt_spec *format,
110 struct string *output, const char *output_encoding)
112 assert (fmt_check_output (format));
113 if (format->type == FMT_A)
115 char *in = CHAR_CAST (char *, value_str (input, format->w));
116 char *out = recode_string (output_encoding, input_encoding,
118 ds_put_cstr (output, out);
121 else if (fmt_get_category (format->type) == FMT_CAT_BINARY)
122 converters[format->type] (input, format,
123 ds_put_uninit (output, format->w));
126 char *utf8_encoded = data_out (input, input_encoding, format);
127 char *output_encoded = recode_string (output_encoding, UTF8,
129 ds_put_cstr (output, output_encoded);
130 free (output_encoded);
136 binary_to_utf8 (const char *in, struct pool *pool)
138 uint8_t *out = pool_alloc_unaligned (pool, strlen (in) * 2 + 1);
143 uint8_t byte = *in++;
144 int mblen = u8_uctomb (p, byte, 2);
150 return CHAR_CAST (char *, out);
153 /* Converts the INPUT value into a UTF-8 encoded string, according to format
154 specification FORMAT.
156 VALUE must be the correct width for FORMAT, that is, its width must be
157 fmt_var_width(FORMAT).
159 ENCODING must be the encoding of INPUT. Normally this can be obtained by
160 calling dict_get_encoding() on the dictionary with which INPUT is
161 associated. ENCODING is only important when FORMAT's type is FMT_A.
163 The return value is dynamically allocated, and must be freed by the caller.
164 If POOL is non-null, then the return value is allocated on that pool. */
166 data_out_pool (const union value *input, const char *encoding,
167 const struct fmt_spec *format, struct pool *pool)
169 assert (fmt_check_output (format));
170 if (format->type == FMT_A)
172 char *in = CHAR_CAST (char *, value_str (input, format->w));
173 return recode_string_pool (UTF8, encoding, in, format->w, pool);
175 else if (fmt_get_category (format->type) == FMT_CAT_BINARY)
179 assert (format->w + 1 <= sizeof tmp);
180 converters[format->type] (input, format, tmp);
181 return binary_to_utf8 (tmp, pool);
185 const struct fmt_number_style *style = settings_get_style (format->type);
186 size_t size = format->w + style->extra_bytes + 1;
189 output = pool_alloc_unaligned (pool, size);
190 converters[format->type] (input, format, output);
196 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
198 return data_out_pool (input, encoding, format, NULL);
202 /* Main conversion functions. */
204 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
207 output_number (const union value *input, const struct fmt_spec *format,
210 double number = input->f;
212 if (number == SYSMIS)
213 output_missing (format, output);
214 else if (!isfinite (number))
215 output_infinite (number, format, output);
218 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
221 rounder_init (&r, number, format->d);
223 if (output_decimal (&r, format, true, output)
224 || output_scientific (number, format, true, output)
225 || output_decimal (&r, format, false, output))
229 if (!output_scientific (number, format, false, output))
230 output_overflow (format, output);
234 /* Outputs N format. */
236 output_N (const union value *input, const struct fmt_spec *format,
239 double number = input->f * power10 (format->d);
240 if (input->f == SYSMIS || number < 0)
241 output_missing (format, output);
245 number = fabs (round (number));
246 if (number < power10 (format->w)
247 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
248 memcpy (output, buf, format->w);
250 output_overflow (format, output);
253 output[format->w] = '\0';
256 /* Outputs Z format. */
258 output_Z (const union value *input, const struct fmt_spec *format,
261 double number = input->f * power10 (format->d);
263 if (input->f == SYSMIS)
264 output_missing (format, output);
265 else if (fabs (number) < power10 (format->w)
266 && sprintf (buf, "%0*.0f", format->w,
267 fabs (round (number))) == format->w)
269 if (number < 0 && strspn (buf, "0") < format->w)
271 char *p = &buf[format->w - 1];
272 *p = "}JKLMNOPQR"[*p - '0'];
274 memcpy (output, buf, format->w);
275 output[format->w] = '\0';
278 output_overflow (format, output);
281 /* Outputs P format. */
283 output_P (const union value *input, const struct fmt_spec *format,
286 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
287 format->w * 2 - 1, output)
289 output[format->w - 1] |= 0xd;
291 output[format->w - 1] |= 0xf;
294 /* Outputs PK format. */
296 output_PK (const union value *input, const struct fmt_spec *format,
299 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
302 /* Outputs IB format. */
304 output_IB (const union value *input, const struct fmt_spec *format,
307 double number = round (input->f * power10 (format->d));
308 if (input->f == SYSMIS
309 || number >= power256 (format->w) / 2 - 1
310 || number < -power256 (format->w) / 2)
311 memset (output, 0, format->w);
314 uint64_t integer = fabs (number);
317 output_binary_integer (integer, format->w,
318 settings_get_output_integer_format (),
322 output[format->w] = '\0';
325 /* Outputs PIB format. */
327 output_PIB (const union value *input, const struct fmt_spec *format,
330 double number = round (input->f * power10 (format->d));
331 if (input->f == SYSMIS
332 || number < 0 || number >= power256 (format->w))
333 memset (output, 0, format->w);
335 output_binary_integer (number, format->w,
336 settings_get_output_integer_format (), output);
338 output[format->w] = '\0';
341 /* Outputs PIBHEX format. */
343 output_PIBHEX (const union value *input, const struct fmt_spec *format,
346 double number = round (input->f);
347 if (input->f == SYSMIS)
348 output_missing (format, output);
349 else if (input->f < 0 || number >= power256 (format->w / 2))
350 output_overflow (format, output);
354 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
355 output_hex (tmp, format->w / 2, output);
360 /* Outputs RB format. */
362 output_RB (const union value *input, const struct fmt_spec *format,
366 memcpy (output, &d, format->w);
368 output[format->w] = '\0';
371 /* Outputs RBHEX format. */
373 output_RBHEX (const union value *input, const struct fmt_spec *format,
378 output_hex (&d, format->w / 2, output);
381 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
382 DATETIME, TIME, and DTIME formats. */
384 output_date (const union value *input, const struct fmt_spec *format,
387 double number = input->f;
388 int year, month, day, yday;
390 const char *template = fmt_date_template (format->type, format->w);
395 if (number == SYSMIS)
398 if (fmt_get_category (format->type) == FMT_CAT_DATE)
402 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
403 &year, &month, &day, &yday);
404 number = fmod (number, 60. * 60. * 24.);
407 year = month = day = yday = 0;
409 while (*template != '\0')
415 while (template[count] == ch)
423 p += sprintf (p, "%02d", day);
425 p += sprintf (p, "%03d", yday);
429 p += sprintf (p, "%02d", month);
432 static const char *const months[12] =
434 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
435 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
437 p = stpcpy (p, months[month - 1]);
444 p += sprintf (p, "%04d", year);
445 else if (format->type == FMT_DATETIME)
446 p = stpcpy (p, "****");
452 int epoch = settings_get_epoch ();
453 int offset = year - epoch;
454 if (offset < 0 || offset > 99)
456 p += sprintf (p, "%02d", abs (year) % 100);
460 p += sprintf (p, "%d", (month - 1) / 3 + 1);
463 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
468 number = fabs (number);
469 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
470 number = fmod (number, 60. * 60. * 24.);
475 number = fabs (number);
476 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
477 number = fmod (number, 60. * 60.);
480 p += sprintf (p, "%02d", (int) floor (number / 60.));
481 number = fmod (number, 60.);
482 excess_width = format->w - (p - tmp);
483 if (excess_width < 0)
485 if (excess_width == 3 || excess_width == 4
486 || (excess_width >= 5 && format->d == 0))
487 p += sprintf (p, ":%02d", (int) number);
488 else if (excess_width >= 5)
490 int d = MIN (format->d, excess_width - 4);
492 sprintf (p, ":%0*.*f", w, d, number);
493 if (settings_get_decimal_char (FMT_F) != '.')
495 char *cp = strchr (p, '.');
497 *cp = settings_get_decimal_char (FMT_F);
510 buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
511 output[format->w] = '\0';
515 output_overflow (format, output);
519 output_missing (format, output);
523 /* Outputs WKDAY format. */
525 output_WKDAY (const union value *input, const struct fmt_spec *format,
528 static const char *const weekdays[7] =
530 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
531 "THURSDAY", "FRIDAY", "SATURDAY",
534 if (input->f >= 1 && input->f < 8)
536 buf_copy_str_rpad (output, format->w,
537 weekdays[(int) input->f - 1], ' ');
538 output[format->w] = '\0';
542 if (input->f != SYSMIS)
543 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
544 output_missing (format, output);
549 /* Outputs MONTH format. */
551 output_MONTH (const union value *input, const struct fmt_spec *format,
554 static const char *const months[12] =
556 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
557 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
560 if (input->f >= 1 && input->f < 13)
562 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
563 output[format->w] = '\0';
567 if (input->f != SYSMIS)
568 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
569 output_missing (format, output);
574 /* Outputs A format. */
576 output_A (const union value *input UNUSED,
577 const struct fmt_spec *format UNUSED, char *output UNUSED)
582 /* Outputs AHEX format. */
584 output_AHEX (const union value *input, const struct fmt_spec *format,
587 output_hex (value_str (input, format->w), format->w / 2, output);
590 /* Decimal and scientific formatting. */
592 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
593 increments *WIDTH by REQUEST and return true.
594 Otherwise returns false without changing *WIDTH. */
596 allocate_space (int request, int max_width, int *width)
598 assert (*width <= max_width);
599 if (request + *width <= max_width)
608 /* Tries to compose the number represented by R, in the style of
609 FORMAT, into OUTPUT. Returns true if successful, false on
610 failure, which occurs if FORMAT's width is too narrow. If
611 REQUIRE_AFFIXES is true, then the prefix and suffix specified
612 by FORMAT's style must be included; otherwise, they may be
613 omitted to make the number fit. */
615 output_decimal (const struct rounder *r, const struct fmt_spec *format,
616 bool require_affixes, char *output)
618 const struct fmt_number_style *style =
619 settings_get_style (format->type);
623 for (decimals = format->d; decimals >= 0; decimals--)
625 /* Formatted version of magnitude of NUMBER. */
628 /* Number of digits in MAGNITUDE's integer and fractional parts. */
631 /* Amount of space within the field width already claimed.
632 Initially this is the width of MAGNITUDE, then it is reduced
633 in stages as space is allocated to prefixes and suffixes and
634 grouping characters. */
637 /* Include various decorations? */
642 /* Position in output. */
645 /* Make sure there's room for the number's magnitude, plus
646 the negative suffix, plus (if negative) the negative
648 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
649 width += style->neg_suffix.width;
651 width += style->neg_prefix.width;
652 if (width > format->w)
655 /* If there's room for the prefix and suffix, allocate
656 space. If the affixes are required, but there's no
658 add_affixes = allocate_space (fmt_affix_width (style),
660 if (!add_affixes && require_affixes)
663 /* Check whether we should include grouping characters.
664 We need room for a complete set or we don't insert any at all.
665 We don't include grouping characters if decimal places were
666 requested but they were all dropped. */
667 add_grouping = (style->grouping != 0
668 && integer_digits > 3
669 && (format->d == 0 || decimals > 0)
670 && allocate_space ((integer_digits - 1) / 3,
673 /* Format the number's magnitude. */
674 rounder_format (r, decimals, magnitude);
676 /* Assemble number. */
678 if (format->w > width)
679 p = mempset (p, ' ', format->w - width);
681 p = stpcpy (p, style->neg_prefix.s);
683 p = stpcpy (p, style->prefix.s);
685 p = mempcpy (p, magnitude, integer_digits);
689 for (i = 0; i < integer_digits; i++)
691 if (i > 0 && (integer_digits - i) % 3 == 0)
692 *p++ = style->grouping;
698 *p++ = style->decimal;
699 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
702 p = stpcpy (p, style->suffix.s);
704 p = stpcpy (p, style->neg_suffix.s);
706 p = mempset (p, ' ', style->neg_suffix.width);
708 assert (p >= output + format->w);
709 assert (p <= output + format->w + style->extra_bytes);
717 /* Formats NUMBER into OUTPUT in scientific notation according to
718 the style of the format specified in FORMAT. */
720 output_scientific (double number, const struct fmt_spec *format,
721 bool require_affixes, char *output)
723 const struct fmt_number_style *style =
724 settings_get_style (format->type);
730 /* Allocate minimum required space. */
731 width = 6 + style->neg_suffix.width;
733 width += style->neg_prefix.width;
734 if (width > format->w)
737 /* Check for room for prefix and suffix. */
738 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
739 if (require_affixes && !add_affixes)
742 /* Figure out number of characters we can use for the fraction,
743 if any. (If that turns out to be 1, then we'll output a
744 decimal point without any digits following; that's what the
745 # flag does in the call to sprintf, below.) */
746 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
747 if (format->type != FMT_E && fraction_width == 1)
749 width += fraction_width;
751 /* Format (except suffix). */
753 if (width < format->w)
754 p = mempset (p, ' ', format->w - width);
756 p = stpcpy (p, style->neg_prefix.s);
758 p = stpcpy (p, style->prefix.s);
759 if (fraction_width > 0)
760 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
762 sprintf (p, "%.0E", fabs (number));
764 /* The C locale always uses a period `.' as a decimal point.
765 Translate to comma if necessary. */
766 if (style->decimal != '.')
768 char *cp = strchr (p, '.');
770 *cp = style->decimal;
773 /* Make exponent have exactly three digits, plus sign. */
775 char *cp = strchr (p, 'E') + 1;
776 long int exponent = strtol (cp, NULL, 10);
777 if (abs (exponent) > 999)
779 sprintf (cp, "%+04ld", exponent);
783 p = strchr (p, '\0');
785 p = stpcpy (p, style->suffix.s);
787 p = stpcpy (p, style->neg_suffix.s);
789 p = mempset (p, ' ', style->neg_suffix.width);
791 assert (p >= output + format->w);
792 assert (p <= output + format->w + style->extra_bytes);
798 /* Returns true if the magnitude represented by R should be
799 rounded up when chopped off at DECIMALS decimal places, false
800 if it should be rounded down. */
802 should_round_up (const struct rounder *r, int decimals)
804 int digit = r->string[r->integer_digits + decimals + 1];
805 assert (digit >= '0' && digit <= '9');
809 /* Initializes R for formatting the magnitude of NUMBER to no
810 more than MAX_DECIMAL decimal places. */
812 rounder_init (struct rounder *r, double number, int max_decimals)
814 assert (fabs (number) < 1e41);
815 assert (max_decimals >= 0 && max_decimals <= 16);
816 if (max_decimals == 0)
818 /* Fast path. No rounding needed.
820 We append ".00" to the integer representation because
821 round_up assumes that fractional digits are present. */
822 sprintf (r->string, "%.0f.00", fabs (round (number)));
828 This is more difficult than it really should be because
829 we have to make sure that numbers that are exactly
830 halfway between two representations are always rounded
831 away from zero. This is not what sprintf normally does
832 (usually it rounds to even), so we have to fake it as
833 best we can, by formatting with extra precision and then
834 doing the rounding ourselves.
836 We take up to two rounds to format numbers. In the
837 first round, we obtain 2 digits of precision beyond
838 those requested by the user. If those digits are
839 exactly "50", then in a second round we format with as
840 many digits as are significant in a "double".
842 It might be better to directly implement our own
843 floating-point formatting routine instead of relying on
844 the system's sprintf implementation. But the classic
845 Steele and White paper on printing floating-point
846 numbers does not hint how to do what we want, and it's
847 not obvious how to change their algorithms to do so. It
848 would also be a lot of work. */
849 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
850 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
852 int binary_exponent, decimal_exponent, format_decimals;
853 frexp (number, &binary_exponent);
854 decimal_exponent = binary_exponent * 3 / 10;
855 format_decimals = (DBL_DIG + 1) - decimal_exponent;
856 if (format_decimals > max_decimals + 2)
857 sprintf (r->string, "%.*f", format_decimals, fabs (number));
861 if (r->string[0] == '0')
862 memmove (r->string, &r->string[1], strlen (r->string));
864 r->leading_zeros = strspn (r->string, "0.");
865 r->leading_nines = strspn (r->string, "9.");
866 r->integer_digits = strchr (r->string, '.') - r->string;
867 assert (r->integer_digits >= 0);
868 r->negative = number < 0;
871 /* Returns the number of characters required to format the
872 magnitude represented by R to DECIMALS decimal places.
873 The return value includes integer digits and a decimal point
874 and fractional digits, if any, but it does not include any
875 negative prefix or suffix or other affixes.
877 *INTEGER_DIGITS is set to the number of digits before the
878 decimal point in the output, between 0 and 40.
880 If R represents a negative number and its rounded
881 representation would include at least one nonzero digit,
882 *NEGATIVE is set to true; otherwise, it is set to false. */
884 rounder_width (const struct rounder *r, int decimals,
885 int *integer_digits, bool *negative)
887 /* Calculate base measures. */
888 int width = r->integer_digits;
890 width += decimals + 1;
891 *integer_digits = r->integer_digits;
892 *negative = r->negative;
894 /* Rounding can cause adjustments. */
895 if (should_round_up (r, decimals))
897 /* Rounding up leading 9s adds a new digit (a 1). */
898 if (r->leading_nines >= width)
907 if (r->leading_zeros >= width)
909 /* All digits that remain after rounding are zeros.
910 Therefore we drop the negative sign. */
912 if (r->integer_digits == 0 && decimals == 0)
914 /* No digits at all are left. We need to display
915 at least a single digit (a zero). */
925 /* Formats the magnitude represented by R into OUTPUT, rounding
926 to DECIMALS decimal places. Exactly as many characters as
927 indicated by rounder_width are written. No terminating null
930 rounder_format (const struct rounder *r, int decimals, char *output)
932 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
933 if (should_round_up (r, decimals))
935 if (r->leading_nines < base_width)
937 /* Rounding up. This is the common case where rounding
938 up doesn't add an extra digit. */
940 memcpy (output, r->string, base_width);
941 for (p = output + base_width - 1; ; p--)
943 assert (p >= output);
946 else if (*p >= '0' && *p <= '8')
957 /* Rounding up leading 9s causes the result to be a 1
958 followed by a number of 0s, plus a decimal point. */
961 p = mempset (p, '0', r->integer_digits);
965 p = mempset (p, '0', decimals);
967 assert (p == output + base_width + 1);
973 if (r->integer_digits != 0 || decimals != 0)
975 /* Common case: just copy the digits. */
976 memcpy (output, r->string, base_width);
980 /* No digits remain. The output is just a zero. */
986 /* Helper functions. */
989 static double PURE_FUNCTION
992 static const double p[] =
994 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
995 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
996 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
997 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
1000 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
1003 /* Returns 256**X. */
1004 static double PURE_FUNCTION
1007 static const double p[] =
1016 72057594037927936.0,
1017 18446744073709551616.0
1019 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
1022 /* Formats non-finite NUMBER into OUTPUT according to the width
1025 output_infinite (double number, const struct fmt_spec *format, char *output)
1027 assert (!isfinite (number));
1035 else if (isinf (number))
1036 s = number > 0 ? "+Infinity" : "-Infinity";
1040 buf_copy_str_lpad (output, format->w, s, ' ');
1043 output_overflow (format, output);
1045 output[format->w] = '\0';
1048 /* Formats OUTPUT as a missing value for the given FORMAT. */
1050 output_missing (const struct fmt_spec *format, char *output)
1052 memset (output, ' ', format->w);
1054 if (format->type != FMT_N)
1056 int dot_ofs = (format->type == FMT_PCT ? 2
1057 : format->type == FMT_E ? 5
1059 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
1062 output[format->w - 1] = '.';
1064 output[format->w] = '\0';
1067 /* Formats OUTPUT for overflow given FORMAT. */
1069 output_overflow (const struct fmt_spec *format, char *output)
1071 memset (output, '*', format->w);
1072 output[format->w] = '\0';
1075 /* Converts the integer part of NUMBER to a packed BCD number
1076 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
1077 the least significant nibble of the final byte in OUTPUT is
1078 set to 0. Returns true if successful, false if NUMBER is not
1079 representable. On failure, OUTPUT is cleared to all zero
1082 output_bcd_integer (double number, int digits, char *output)
1086 assert (digits < sizeof decimal);
1088 output[DIV_RND_UP (digits, 2)] = '\0';
1089 if (number != SYSMIS
1091 && number < power10 (digits)
1092 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1094 const char *src = decimal;
1097 for (i = 0; i < digits / 2; i++)
1099 int d0 = *src++ - '0';
1100 int d1 = *src++ - '0';
1101 *output++ = (d0 << 4) + d1;
1104 *output = (*src - '0') << 4;
1110 memset (output, 0, DIV_RND_UP (digits, 2));
1115 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1116 given INTEGER_FORMAT. */
1118 output_binary_integer (uint64_t value, int bytes,
1119 enum integer_format integer_format, char *output)
1121 integer_put (value, integer_format, output, bytes);
1124 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1125 digits in OUTPUT. */
1127 output_hex (const void *data_, size_t bytes, char *output)
1129 const uint8_t *data = data_;
1132 for (i = 0; i < bytes; i++)
1134 static const char hex_digits[] = "0123456789ABCDEF";
1135 *output++ = hex_digits[data[i] >> 4];
1136 *output++ = hex_digits[data[i] & 15];