1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2009, 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/>. */
28 #include <data/calendar.h>
29 #include <data/format.h>
30 #include <data/settings.h>
31 #include <data/value.h>
33 #include <libpspp/assertion.h>
34 #include <libpspp/float-format.h>
35 #include <libpspp/integer-format.h>
36 #include <libpspp/message.h>
37 #include <libpspp/misc.h>
38 #include <libpspp/str.h>
39 #include <libpspp/pool.h>
40 #include <libpspp/i18n.h>
45 #define _(msgid) gettext (msgid)
47 /* A representation of a number that can be quickly rounded to
48 any desired number of decimal places (up to a specified
52 char string[64]; /* Magnitude of number with excess precision. */
53 int integer_digits; /* Number of digits before decimal point. */
54 int leading_nines; /* Number of `9's or `.'s at start of string. */
55 int leading_zeros; /* Number of `0's or `.'s at start of string. */
56 bool negative; /* Is the number negative? */
59 static void rounder_init (struct rounder *, double number, int max_decimals);
60 static int rounder_width (const struct rounder *, int decimals,
61 int *integer_digits, bool *negative);
62 static void rounder_format (const struct rounder *, int decimals,
65 typedef void data_out_converter_func (const union value *,
66 const struct fmt_spec *,
68 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
69 static data_out_converter_func output_##METHOD;
72 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
73 bool require_affixes, char *);
74 static bool output_scientific (double, const struct fmt_spec *,
75 bool require_affixes, char *);
77 static double power10 (int) PURE_FUNCTION;
78 static double power256 (int) PURE_FUNCTION;
80 static void output_infinite (double, const struct fmt_spec *, char *);
81 static void output_missing (const struct fmt_spec *, char *);
82 static void output_overflow (const struct fmt_spec *, char *);
83 static bool output_bcd_integer (double, int digits, char *);
84 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
86 static void output_hex (const void *, size_t bytes, char *);
89 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
91 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
95 /* Similar to data_out. Additionally recodes the output from
96 native form into the given legacy character ENCODING.
97 OUTPUT must be provided by the caller and must be at least
98 FORMAT->w long. No null terminator is appended to OUTPUT.
101 data_out_legacy (const union value *input, const char *encoding,
102 const struct fmt_spec *format, char *output)
104 assert (fmt_check_output (format));
106 converters[format->type] (input, format, output);
107 if (0 != strcmp (encoding, C_ENCODING)
108 && fmt_get_category (format->type) != FMT_CAT_BINARY)
110 char *s = recode_string (encoding, C_ENCODING, output, format->w );
111 memcpy (output, s, format->w);
116 /* Converts the INPUT value into a UTF8 encoded string, according
117 to format specification FORMAT.
119 VALUE must be the correct width for FORMAT, that is, its
120 width must be fmt_var_width(FORMAT).
122 ENCODING must be the encoding of INPUT. Normally this can
123 be obtained by calling dict_get_encoding on the dictionary
124 with which INPUT is associated.
126 The return value is dynamically allocated, and must be freed
127 by the caller. If POOL is non-null, then the return value is
128 allocated on that pool.
131 data_out_pool (const union value *input, const char *encoding,
132 const struct fmt_spec *format, struct pool *pool)
136 assert (fmt_check_output (format));
138 output = xmalloc (format->w + 1);
140 converters[format->type] (input, format, output);
142 t = recode_string_pool (UTF8, encoding, output, format->w, pool);
148 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
150 return data_out_pool (input, encoding, format, NULL);
154 /* Main conversion functions. */
156 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
159 output_number (const union value *input, const struct fmt_spec *format,
162 double number = input->f;
164 if (number == SYSMIS)
165 output_missing (format, output);
166 else if (!isfinite (number))
167 output_infinite (number, format, output);
170 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
173 rounder_init (&r, number, format->d);
175 if (output_decimal (&r, format, true, output)
176 || output_scientific (number, format, true, output)
177 || output_decimal (&r, format, false, output))
181 if (!output_scientific (number, format, false, output))
182 output_overflow (format, output);
186 /* Outputs N format. */
188 output_N (const union value *input, const struct fmt_spec *format,
191 double number = input->f * power10 (format->d);
192 if (input->f == SYSMIS || number < 0)
193 output_missing (format, output);
197 number = fabs (round (number));
198 if (number < power10 (format->w)
199 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
200 memcpy (output, buf, format->w);
202 output_overflow (format, output);
205 output[format->w] = '\0';
208 /* Outputs Z format. */
210 output_Z (const union value *input, const struct fmt_spec *format,
213 double number = input->f * power10 (format->d);
215 if (input->f == SYSMIS)
216 output_missing (format, output);
217 else if (fabs (number) >= power10 (format->w)
218 || sprintf (buf, "%0*.0f", format->w,
219 fabs (round (number))) != format->w)
220 output_overflow (format, output);
223 if (number < 0 && strspn (buf, "0") < format->w)
225 char *p = &buf[format->w - 1];
226 *p = "}JKLMNOPQR"[*p - '0'];
228 memcpy (output, buf, format->w);
229 output[format->w] = '\0';
233 /* Outputs P format. */
235 output_P (const union value *input, const struct fmt_spec *format,
238 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
239 format->w * 2 - 1, output)
241 output[format->w - 1] |= 0xd;
243 output[format->w - 1] |= 0xf;
246 /* Outputs PK format. */
248 output_PK (const union value *input, const struct fmt_spec *format,
251 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
254 /* Outputs IB format. */
256 output_IB (const union value *input, const struct fmt_spec *format,
259 double number = round (input->f * power10 (format->d));
260 if (input->f == SYSMIS
261 || number >= power256 (format->w) / 2 - 1
262 || number < -power256 (format->w) / 2)
263 memset (output, 0, format->w);
266 uint64_t integer = fabs (number);
269 output_binary_integer (integer, format->w,
270 settings_get_output_integer_format (),
274 output[format->w] = '\0';
277 /* Outputs PIB format. */
279 output_PIB (const union value *input, const struct fmt_spec *format,
282 double number = round (input->f * power10 (format->d));
283 if (input->f == SYSMIS
284 || number < 0 || number >= power256 (format->w))
285 memset (output, 0, format->w);
287 output_binary_integer (number, format->w,
288 settings_get_output_integer_format (), output);
290 output[format->w] = '\0';
293 /* Outputs PIBHEX format. */
295 output_PIBHEX (const union value *input, const struct fmt_spec *format,
298 double number = round (input->f);
299 if (input->f == SYSMIS)
300 output_missing (format, output);
301 else if (input->f < 0 || number >= power256 (format->w / 2))
302 output_overflow (format, output);
306 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
307 output_hex (tmp, format->w / 2, output);
312 /* Outputs RB format. */
314 output_RB (const union value *input, const struct fmt_spec *format,
318 memcpy (output, &d, format->w);
320 output[format->w] = '\0';
323 /* Outputs RBHEX format. */
325 output_RBHEX (const union value *input, const struct fmt_spec *format,
330 output_hex (&d, format->w / 2, output);
333 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
334 DATETIME, TIME, and DTIME formats. */
336 output_date (const union value *input, const struct fmt_spec *format,
339 double number = input->f;
340 int year, month, day, yday;
342 const char *template = fmt_date_template (format->type);
343 size_t template_width = strlen (template);
344 int excess_width = format->w - template_width;
349 assert (format->w >= template_width);
350 if (number == SYSMIS)
353 if (fmt_get_category (format->type) == FMT_CAT_DATE)
357 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
358 &year, &month, &day, &yday);
359 number = fmod (number, 60. * 60. * 24.);
362 year = month = day = yday = 0;
364 while (*template != '\0')
368 while (template[count] == ch)
376 p += sprintf (p, "%02d", day);
378 p += sprintf (p, "%03d", yday);
382 p += sprintf (p, "%02d", month);
385 static const char *const months[12] =
387 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
388 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
390 p = stpcpy (p, months[month - 1]);
394 if (count >= 4 || excess_width >= 2)
397 p += sprintf (p, "%04d", year);
398 else if (format->type == FMT_DATETIME)
399 p = stpcpy (p, "****");
405 int epoch = settings_get_epoch ();
406 int offset = year - epoch;
407 if (offset < 0 || offset > 99)
409 p += sprintf (p, "%02d", abs (year) % 100);
413 p += sprintf (p, "%d", (month - 1) / 3 + 1);
416 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
421 number = fabs (number);
422 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
423 number = fmod (number, 60. * 60. * 24.);
428 number = fabs (number);
429 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
430 number = fmod (number, 60. * 60.);
433 p += sprintf (p, "%02d", (int) floor (number / 60.));
434 number = fmod (number, 60.);
435 excess_width = format->w - (p - tmp);
436 if (excess_width < 0)
438 if (excess_width == 3 || excess_width == 4
439 || (excess_width >= 5 && format->d == 0))
440 p += sprintf (p, ":%02d", (int) number);
441 else if (excess_width >= 5)
443 int d = MIN (format->d, excess_width - 4);
445 sprintf (p, ":%0*.*f", w, d, number);
446 if (settings_get_decimal_char (FMT_F) != '.')
448 char *cp = strchr (p, '.');
450 *cp = settings_get_decimal_char (FMT_F);
465 buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
466 output[format->w] = '\0';
470 output_overflow (format, output);
474 output_missing (format, output);
478 /* Outputs WKDAY format. */
480 output_WKDAY (const union value *input, const struct fmt_spec *format,
483 static const char *const weekdays[7] =
485 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
486 "THURSDAY", "FRIDAY", "SATURDAY",
489 if (input->f >= 1 && input->f < 8)
491 buf_copy_str_rpad (output, format->w,
492 weekdays[(int) input->f - 1], ' ');
493 output[format->w] = '\0';
497 if (input->f != SYSMIS)
498 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
499 output_missing (format, output);
504 /* Outputs MONTH format. */
506 output_MONTH (const union value *input, const struct fmt_spec *format,
509 static const char *const months[12] =
511 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
512 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
515 if (input->f >= 1 && input->f < 13)
517 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
518 output[format->w] = '\0';
522 if (input->f != SYSMIS)
523 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
524 output_missing (format, output);
529 /* Outputs A format. */
531 output_A (const union value *input, const struct fmt_spec *format,
534 memcpy (output, value_str (input, format->w), format->w);
535 output[format->w] = '\0';
538 /* Outputs AHEX format. */
540 output_AHEX (const union value *input, const struct fmt_spec *format,
543 output_hex (value_str (input, format->w), format->w / 2, output);
546 /* Decimal and scientific formatting. */
548 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
549 increments *WIDTH by REQUEST and return true.
550 Otherwise returns false without changing *WIDTH. */
552 allocate_space (int request, int max_width, int *width)
554 assert (*width <= max_width);
555 if (request + *width <= max_width)
564 /* Tries to compose the number represented by R, in the style of
565 FORMAT, into OUTPUT. Returns true if successful, false on
566 failure, which occurs if FORMAT's width is too narrow. If
567 REQUIRE_AFFIXES is true, then the prefix and suffix specified
568 by FORMAT's style must be included; otherwise, they may be
569 omitted to make the number fit. */
571 output_decimal (const struct rounder *r, const struct fmt_spec *format,
572 bool require_affixes, char *output)
574 const struct fmt_number_style *style =
575 settings_get_style (format->type);
579 for (decimals = format->d; decimals >= 0; decimals--)
581 /* Formatted version of magnitude of NUMBER. */
584 /* Number of digits in MAGNITUDE's integer and fractional parts. */
587 /* Amount of space within the field width already claimed.
588 Initially this is the width of MAGNITUDE, then it is reduced
589 in stages as space is allocated to prefixes and suffixes and
590 grouping characters. */
593 /* Include various decorations? */
598 /* Position in output. */
601 /* Make sure there's room for the number's magnitude, plus
602 the negative suffix, plus (if negative) the negative
604 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
605 width += strlen (style->neg_suffix.s);
607 width += strlen (style->neg_prefix.s);
608 if (width > format->w)
611 /* If there's room for the prefix and suffix, allocate
612 space. If the affixes are required, but there's no
614 add_affixes = allocate_space (fmt_affix_width (style),
616 if (!add_affixes && require_affixes)
619 /* Check whether we should include grouping characters.
620 We need room for a complete set or we don't insert any at all.
621 We don't include grouping characters if decimal places were
622 requested but they were all dropped. */
623 add_grouping = (style->grouping != 0
624 && integer_digits > 3
625 && (format->d == 0 || decimals > 0)
626 && allocate_space ((integer_digits - 1) / 3,
629 /* Format the number's magnitude. */
630 rounder_format (r, decimals, magnitude);
632 /* Assemble number. */
634 if (format->w > width)
635 p = mempset (p, ' ', format->w - width);
637 p = stpcpy (p, style->neg_prefix.s);
639 p = stpcpy (p, style->prefix.s);
641 p = mempcpy (p, magnitude, integer_digits);
645 for (i = 0; i < integer_digits; i++)
647 if (i > 0 && (integer_digits - i) % 3 == 0)
648 *p++ = style->grouping;
654 *p++ = style->decimal;
655 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
658 p = stpcpy (p, style->suffix.s);
660 p = stpcpy (p, style->neg_suffix.s);
662 p = mempset (p, ' ', strlen (style->neg_suffix.s));
663 assert (p == output + format->w);
670 /* Formats NUMBER into OUTPUT in scientific notation according to
671 the style of the format specified in FORMAT. */
673 output_scientific (double number, const struct fmt_spec *format,
674 bool require_affixes, char *output)
676 const struct fmt_number_style *style =
677 settings_get_style (format->type);
683 /* Allocate minimum required space. */
684 width = 6 + strlen (style->neg_suffix.s);
686 width += strlen (style->neg_prefix.s);
687 if (width > format->w)
690 /* Check for room for prefix and suffix. */
691 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
692 if (require_affixes && !add_affixes)
695 /* Figure out number of characters we can use for the fraction,
696 if any. (If that turns out to be 1, then we'll output a
697 decimal point without any digits following; that's what the
698 # flag does in the call to sprintf, below.) */
699 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
700 if (format->type != FMT_E && fraction_width == 1)
702 width += fraction_width;
704 /* Format (except suffix). */
706 if (width < format->w)
707 p = mempset (p, ' ', format->w - width);
709 p = stpcpy (p, style->neg_prefix.s);
711 p = stpcpy (p, style->prefix.s);
712 if (fraction_width > 0)
713 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
715 sprintf (p, "%.0E", fabs (number));
717 /* The C locale always uses a period `.' as a decimal point.
718 Translate to comma if necessary. */
719 if (style->decimal != '.')
721 char *cp = strchr (p, '.');
723 *cp = style->decimal;
726 /* Make exponent have exactly three digits, plus sign. */
728 char *cp = strchr (p, 'E') + 1;
729 long int exponent = strtol (cp, NULL, 10);
730 if (abs (exponent) > 999)
732 sprintf (cp, "%+04ld", exponent);
736 p = strchr (p, '\0');
738 p = stpcpy (p, style->suffix.s);
740 p = stpcpy (p, style->neg_suffix.s);
742 p = mempset (p, ' ', strlen (style->neg_suffix.s));
744 assert (p == buf + format->w);
745 memcpy (output, buf, format->w);
746 output[format->w] = '\0';
751 /* Returns true if the magnitude represented by R should be
752 rounded up when chopped off at DECIMALS decimal places, false
753 if it should be rounded down. */
755 should_round_up (const struct rounder *r, int decimals)
757 int digit = r->string[r->integer_digits + decimals + 1];
758 assert (digit >= '0' && digit <= '9');
762 /* Initializes R for formatting the magnitude of NUMBER to no
763 more than MAX_DECIMAL decimal places. */
765 rounder_init (struct rounder *r, double number, int max_decimals)
767 assert (fabs (number) < 1e41);
768 assert (max_decimals >= 0 && max_decimals <= 16);
769 if (max_decimals == 0)
771 /* Fast path. No rounding needed.
773 We append ".00" to the integer representation because
774 round_up assumes that fractional digits are present. */
775 sprintf (r->string, "%.0f.00", fabs (round (number)));
781 This is more difficult than it really should be because
782 we have to make sure that numbers that are exactly
783 halfway between two representations are always rounded
784 away from zero. This is not what sprintf normally does
785 (usually it rounds to even), so we have to fake it as
786 best we can, by formatting with extra precision and then
787 doing the rounding ourselves.
789 We take up to two rounds to format numbers. In the
790 first round, we obtain 2 digits of precision beyond
791 those requested by the user. If those digits are
792 exactly "50", then in a second round we format with as
793 many digits as are significant in a "double".
795 It might be better to directly implement our own
796 floating-point formatting routine instead of relying on
797 the system's sprintf implementation. But the classic
798 Steele and White paper on printing floating-point
799 numbers does not hint how to do what we want, and it's
800 not obvious how to change their algorithms to do so. It
801 would also be a lot of work. */
802 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
803 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
805 int binary_exponent, decimal_exponent, format_decimals;
806 frexp (number, &binary_exponent);
807 decimal_exponent = binary_exponent * 3 / 10;
808 format_decimals = (DBL_DIG + 1) - decimal_exponent;
809 if (format_decimals > max_decimals + 2)
810 sprintf (r->string, "%.*f", format_decimals, fabs (number));
814 if (r->string[0] == '0')
815 memmove (r->string, &r->string[1], strlen (r->string));
817 r->leading_zeros = strspn (r->string, "0.");
818 r->leading_nines = strspn (r->string, "9.");
819 r->integer_digits = strchr (r->string, '.') - r->string;
820 r->negative = number < 0;
823 /* Returns the number of characters required to format the
824 magnitude represented by R to DECIMALS decimal places.
825 The return value includes integer digits and a decimal point
826 and fractional digits, if any, but it does not include any
827 negative prefix or suffix or other affixes.
829 *INTEGER_DIGITS is set to the number of digits before the
830 decimal point in the output, between 0 and 40.
832 If R represents a negative number and its rounded
833 representation would include at least one nonzero digit,
834 *NEGATIVE is set to true; otherwise, it is set to false. */
836 rounder_width (const struct rounder *r, int decimals,
837 int *integer_digits, bool *negative)
839 /* Calculate base measures. */
840 int width = r->integer_digits;
842 width += decimals + 1;
843 *integer_digits = r->integer_digits;
844 *negative = r->negative;
846 /* Rounding can cause adjustments. */
847 if (should_round_up (r, decimals))
849 /* Rounding up leading 9s adds a new digit (a 1). */
850 if (r->leading_nines >= width)
859 if (r->leading_zeros >= width)
861 /* All digits that remain after rounding are zeros.
862 Therefore we drop the negative sign. */
864 if (r->integer_digits == 0 && decimals == 0)
866 /* No digits at all are left. We need to display
867 at least a single digit (a zero). */
877 /* Formats the magnitude represented by R into OUTPUT, rounding
878 to DECIMALS decimal places. Exactly as many characters as
879 indicated by rounder_width are written. No terminating null
882 rounder_format (const struct rounder *r, int decimals, char *output)
884 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
885 if (should_round_up (r, decimals))
887 if (r->leading_nines < base_width)
889 /* Rounding up. This is the common case where rounding
890 up doesn't add an extra digit. */
892 memcpy (output, r->string, base_width);
893 for (p = output + base_width - 1; ; p--)
895 assert (p >= output);
898 else if (*p >= '0' && *p <= '8')
909 /* Rounding up leading 9s causes the result to be a 1
910 followed by a number of 0s, plus a decimal point. */
913 p = mempset (p, '0', r->integer_digits);
917 p = mempset (p, '0', decimals);
919 assert (p == output + base_width + 1);
925 if (r->integer_digits != 0 || decimals != 0)
927 /* Common case: just copy the digits. */
928 memcpy (output, r->string, base_width);
932 /* No digits remain. The output is just a zero. */
938 /* Helper functions. */
941 static double PURE_FUNCTION
944 static const double p[] =
946 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
947 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
948 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
949 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
952 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
955 /* Returns 256**X. */
956 static double PURE_FUNCTION
959 static const double p[] =
969 18446744073709551616.0
971 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
974 /* Formats non-finite NUMBER into OUTPUT according to the width
977 output_infinite (double number, const struct fmt_spec *format, char *output)
979 assert (!isfinite (number));
987 else if (isinf (number))
988 s = number > 0 ? "+Infinity" : "-Infinity";
992 buf_copy_str_lpad (output, format->w, s, ' ');
995 output_overflow (format, output);
997 output[format->w] = '\0';
1000 /* Formats OUTPUT as a missing value for the given FORMAT. */
1002 output_missing (const struct fmt_spec *format, char *output)
1004 memset (output, ' ', format->w);
1006 if (format->type != FMT_N)
1008 int dot_ofs = (format->type == FMT_PCT ? 2
1009 : format->type == FMT_E ? 5
1011 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
1014 output[format->w - 1] = '.';
1016 output[format->w] = '\0';
1019 /* Formats OUTPUT for overflow given FORMAT. */
1021 output_overflow (const struct fmt_spec *format, char *output)
1023 memset (output, '*', format->w);
1024 output[format->w] = '\0';
1027 /* Converts the integer part of NUMBER to a packed BCD number
1028 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
1029 the least significant nibble of the final byte in OUTPUT is
1030 set to 0. Returns true if successful, false if NUMBER is not
1031 representable. On failure, OUTPUT is cleared to all zero
1034 output_bcd_integer (double number, int digits, char *output)
1038 assert (digits < sizeof decimal);
1040 output[DIV_RND_UP (digits, 2)] = '\0';
1041 if (number != SYSMIS
1043 && number < power10 (digits)
1044 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1046 const char *src = decimal;
1049 for (i = 0; i < digits / 2; i++)
1051 int d0 = *src++ - '0';
1052 int d1 = *src++ - '0';
1053 *output++ = (d0 << 4) + d1;
1056 *output = (*src - '0') << 4;
1062 memset (output, 0, DIV_RND_UP (digits, 2));
1067 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1068 given INTEGER_FORMAT. */
1070 output_binary_integer (uint64_t value, int bytes,
1071 enum integer_format integer_format, char *output)
1073 integer_put (value, integer_format, output, bytes);
1076 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1077 digits in OUTPUT. */
1079 output_hex (const void *data_, size_t bytes, char *output)
1081 const uint8_t *data = data_;
1084 for (i = 0; i < bytes; i++)
1086 static const char hex_digits[] = "0123456789ABCDEF";
1087 *output++ = hex_digits[data[i] >> 4];
1088 *output++ = hex_digits[data[i] & 15];