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)
134 const struct fmt_number_style *style = settings_get_style (format->type);
137 assert (fmt_check_output (format));
139 output = xmalloc (format->w + style->extra_bytes + 1);
141 converters[format->type] (input, format, output);
143 t = recode_string_pool (UTF8, encoding, output, format->w, pool);
149 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
151 return data_out_pool (input, encoding, format, NULL);
155 /* Main conversion functions. */
157 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
160 output_number (const union value *input, const struct fmt_spec *format,
163 double number = input->f;
165 if (number == SYSMIS)
166 output_missing (format, output);
167 else if (!isfinite (number))
168 output_infinite (number, format, output);
171 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
174 rounder_init (&r, number, format->d);
176 if (output_decimal (&r, format, true, output)
177 || output_scientific (number, format, true, output)
178 || output_decimal (&r, format, false, output))
182 if (!output_scientific (number, format, false, output))
183 output_overflow (format, output);
187 /* Outputs N format. */
189 output_N (const union value *input, const struct fmt_spec *format,
192 double number = input->f * power10 (format->d);
193 if (input->f == SYSMIS || number < 0)
194 output_missing (format, output);
198 number = fabs (round (number));
199 if (number < power10 (format->w)
200 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
201 memcpy (output, buf, format->w);
203 output_overflow (format, output);
206 output[format->w] = '\0';
209 /* Outputs Z format. */
211 output_Z (const union value *input, const struct fmt_spec *format,
214 double number = input->f * power10 (format->d);
216 if (input->f == SYSMIS)
217 output_missing (format, output);
218 else if (fabs (number) < power10 (format->w)
219 && sprintf (buf, "%0*.0f", format->w,
220 fabs (round (number))) == format->w)
222 if (number < 0 && strspn (buf, "0") < format->w)
224 char *p = &buf[format->w - 1];
225 *p = "}JKLMNOPQR"[*p - '0'];
227 memcpy (output, buf, format->w);
228 output[format->w] = '\0';
231 output_overflow (format, output);
234 /* Outputs P format. */
236 output_P (const union value *input, const struct fmt_spec *format,
239 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
240 format->w * 2 - 1, output)
242 output[format->w - 1] |= 0xd;
244 output[format->w - 1] |= 0xf;
247 /* Outputs PK format. */
249 output_PK (const union value *input, const struct fmt_spec *format,
252 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
255 /* Outputs IB format. */
257 output_IB (const union value *input, const struct fmt_spec *format,
260 double number = round (input->f * power10 (format->d));
261 if (input->f == SYSMIS
262 || number >= power256 (format->w) / 2 - 1
263 || number < -power256 (format->w) / 2)
264 memset (output, 0, format->w);
267 uint64_t integer = fabs (number);
270 output_binary_integer (integer, format->w,
271 settings_get_output_integer_format (),
275 output[format->w] = '\0';
278 /* Outputs PIB format. */
280 output_PIB (const union value *input, const struct fmt_spec *format,
283 double number = round (input->f * power10 (format->d));
284 if (input->f == SYSMIS
285 || number < 0 || number >= power256 (format->w))
286 memset (output, 0, format->w);
288 output_binary_integer (number, format->w,
289 settings_get_output_integer_format (), output);
291 output[format->w] = '\0';
294 /* Outputs PIBHEX format. */
296 output_PIBHEX (const union value *input, const struct fmt_spec *format,
299 double number = round (input->f);
300 if (input->f == SYSMIS)
301 output_missing (format, output);
302 else if (input->f < 0 || number >= power256 (format->w / 2))
303 output_overflow (format, output);
307 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
308 output_hex (tmp, format->w / 2, output);
313 /* Outputs RB format. */
315 output_RB (const union value *input, const struct fmt_spec *format,
319 memcpy (output, &d, format->w);
321 output[format->w] = '\0';
324 /* Outputs RBHEX format. */
326 output_RBHEX (const union value *input, const struct fmt_spec *format,
331 output_hex (&d, format->w / 2, output);
334 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
335 DATETIME, TIME, and DTIME formats. */
337 output_date (const union value *input, const struct fmt_spec *format,
340 double number = input->f;
341 int year, month, day, yday;
343 const char *template = fmt_date_template (format->type);
344 size_t template_width = strlen (template);
345 int excess_width = format->w - template_width;
350 assert (format->w >= template_width);
351 if (number == SYSMIS)
354 if (fmt_get_category (format->type) == FMT_CAT_DATE)
358 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
359 &year, &month, &day, &yday);
360 number = fmod (number, 60. * 60. * 24.);
363 year = month = day = yday = 0;
365 while (*template != '\0')
369 while (template[count] == ch)
377 p += sprintf (p, "%02d", day);
379 p += sprintf (p, "%03d", yday);
383 p += sprintf (p, "%02d", month);
386 static const char *const months[12] =
388 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
389 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
391 p = stpcpy (p, months[month - 1]);
395 if (count >= 4 || excess_width >= 2)
398 p += sprintf (p, "%04d", year);
399 else if (format->type == FMT_DATETIME)
400 p = stpcpy (p, "****");
406 int epoch = settings_get_epoch ();
407 int offset = year - epoch;
408 if (offset < 0 || offset > 99)
410 p += sprintf (p, "%02d", abs (year) % 100);
414 p += sprintf (p, "%d", (month - 1) / 3 + 1);
417 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
422 number = fabs (number);
423 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
424 number = fmod (number, 60. * 60. * 24.);
429 number = fabs (number);
430 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
431 number = fmod (number, 60. * 60.);
434 p += sprintf (p, "%02d", (int) floor (number / 60.));
435 number = fmod (number, 60.);
436 excess_width = format->w - (p - tmp);
437 if (excess_width < 0)
439 if (excess_width == 3 || excess_width == 4
440 || (excess_width >= 5 && format->d == 0))
441 p += sprintf (p, ":%02d", (int) number);
442 else if (excess_width >= 5)
444 int d = MIN (format->d, excess_width - 4);
446 sprintf (p, ":%0*.*f", w, d, number);
447 if (settings_get_decimal_char (FMT_F) != '.')
449 char *cp = strchr (p, '.');
451 *cp = settings_get_decimal_char (FMT_F);
466 buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
467 output[format->w] = '\0';
471 output_overflow (format, output);
475 output_missing (format, output);
479 /* Outputs WKDAY format. */
481 output_WKDAY (const union value *input, const struct fmt_spec *format,
484 static const char *const weekdays[7] =
486 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
487 "THURSDAY", "FRIDAY", "SATURDAY",
490 if (input->f >= 1 && input->f < 8)
492 buf_copy_str_rpad (output, format->w,
493 weekdays[(int) input->f - 1], ' ');
494 output[format->w] = '\0';
498 if (input->f != SYSMIS)
499 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
500 output_missing (format, output);
505 /* Outputs MONTH format. */
507 output_MONTH (const union value *input, const struct fmt_spec *format,
510 static const char *const months[12] =
512 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
513 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
516 if (input->f >= 1 && input->f < 13)
518 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
519 output[format->w] = '\0';
523 if (input->f != SYSMIS)
524 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
525 output_missing (format, output);
530 /* Outputs A format. */
532 output_A (const union value *input, const struct fmt_spec *format,
535 memcpy (output, value_str (input, format->w), format->w);
536 output[format->w] = '\0';
539 /* Outputs AHEX format. */
541 output_AHEX (const union value *input, const struct fmt_spec *format,
544 output_hex (value_str (input, format->w), format->w / 2, output);
547 /* Decimal and scientific formatting. */
549 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
550 increments *WIDTH by REQUEST and return true.
551 Otherwise returns false without changing *WIDTH. */
553 allocate_space (int request, int max_width, int *width)
555 assert (*width <= max_width);
556 if (request + *width <= max_width)
565 /* Tries to compose the number represented by R, in the style of
566 FORMAT, into OUTPUT. Returns true if successful, false on
567 failure, which occurs if FORMAT's width is too narrow. If
568 REQUIRE_AFFIXES is true, then the prefix and suffix specified
569 by FORMAT's style must be included; otherwise, they may be
570 omitted to make the number fit. */
572 output_decimal (const struct rounder *r, const struct fmt_spec *format,
573 bool require_affixes, char *output)
575 const struct fmt_number_style *style =
576 settings_get_style (format->type);
580 for (decimals = format->d; decimals >= 0; decimals--)
582 /* Formatted version of magnitude of NUMBER. */
585 /* Number of digits in MAGNITUDE's integer and fractional parts. */
588 /* Amount of space within the field width already claimed.
589 Initially this is the width of MAGNITUDE, then it is reduced
590 in stages as space is allocated to prefixes and suffixes and
591 grouping characters. */
594 /* Include various decorations? */
599 /* Position in output. */
602 /* Make sure there's room for the number's magnitude, plus
603 the negative suffix, plus (if negative) the negative
605 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
606 width += style->neg_suffix.width;
608 width += style->neg_prefix.width;
609 if (width > format->w)
612 /* If there's room for the prefix and suffix, allocate
613 space. If the affixes are required, but there's no
615 add_affixes = allocate_space (fmt_affix_width (style),
617 if (!add_affixes && require_affixes)
620 /* Check whether we should include grouping characters.
621 We need room for a complete set or we don't insert any at all.
622 We don't include grouping characters if decimal places were
623 requested but they were all dropped. */
624 add_grouping = (style->grouping != 0
625 && integer_digits > 3
626 && (format->d == 0 || decimals > 0)
627 && allocate_space ((integer_digits - 1) / 3,
630 /* Format the number's magnitude. */
631 rounder_format (r, decimals, magnitude);
633 /* Assemble number. */
635 if (format->w > width)
636 p = mempset (p, ' ', format->w - width);
638 p = stpcpy (p, style->neg_prefix.s);
640 p = stpcpy (p, style->prefix.s);
642 p = mempcpy (p, magnitude, integer_digits);
646 for (i = 0; i < integer_digits; i++)
648 if (i > 0 && (integer_digits - i) % 3 == 0)
649 *p++ = style->grouping;
655 *p++ = style->decimal;
656 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
659 p = stpcpy (p, style->suffix.s);
661 p = stpcpy (p, style->neg_suffix.s);
663 p = mempset (p, ' ', style->neg_suffix.width);
665 assert (p >= output + format->w);
666 assert (p <= output + format->w + style->extra_bytes);
674 /* Formats NUMBER into OUTPUT in scientific notation according to
675 the style of the format specified in FORMAT. */
677 output_scientific (double number, const struct fmt_spec *format,
678 bool require_affixes, char *output)
680 const struct fmt_number_style *style =
681 settings_get_style (format->type);
687 /* Allocate minimum required space. */
688 width = 6 + style->neg_suffix.width;
690 width += style->neg_prefix.width;
691 if (width > format->w)
694 /* Check for room for prefix and suffix. */
695 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
696 if (require_affixes && !add_affixes)
699 /* Figure out number of characters we can use for the fraction,
700 if any. (If that turns out to be 1, then we'll output a
701 decimal point without any digits following; that's what the
702 # flag does in the call to sprintf, below.) */
703 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
704 if (format->type != FMT_E && fraction_width == 1)
706 width += fraction_width;
708 /* Format (except suffix). */
710 if (width < format->w)
711 p = mempset (p, ' ', format->w - width);
713 p = stpcpy (p, style->neg_prefix.s);
715 p = stpcpy (p, style->prefix.s);
716 if (fraction_width > 0)
717 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
719 sprintf (p, "%.0E", fabs (number));
721 /* The C locale always uses a period `.' as a decimal point.
722 Translate to comma if necessary. */
723 if (style->decimal != '.')
725 char *cp = strchr (p, '.');
727 *cp = style->decimal;
730 /* Make exponent have exactly three digits, plus sign. */
732 char *cp = strchr (p, 'E') + 1;
733 long int exponent = strtol (cp, NULL, 10);
734 if (abs (exponent) > 999)
736 sprintf (cp, "%+04ld", exponent);
740 p = strchr (p, '\0');
742 p = stpcpy (p, style->suffix.s);
744 p = stpcpy (p, style->neg_suffix.s);
746 p = mempset (p, ' ', style->neg_suffix.width);
748 assert (p >= output + format->w);
749 assert (p <= output + format->w + style->extra_bytes);
755 /* Returns true if the magnitude represented by R should be
756 rounded up when chopped off at DECIMALS decimal places, false
757 if it should be rounded down. */
759 should_round_up (const struct rounder *r, int decimals)
761 int digit = r->string[r->integer_digits + decimals + 1];
762 assert (digit >= '0' && digit <= '9');
766 /* Initializes R for formatting the magnitude of NUMBER to no
767 more than MAX_DECIMAL decimal places. */
769 rounder_init (struct rounder *r, double number, int max_decimals)
771 assert (fabs (number) < 1e41);
772 assert (max_decimals >= 0 && max_decimals <= 16);
773 if (max_decimals == 0)
775 /* Fast path. No rounding needed.
777 We append ".00" to the integer representation because
778 round_up assumes that fractional digits are present. */
779 sprintf (r->string, "%.0f.00", fabs (round (number)));
785 This is more difficult than it really should be because
786 we have to make sure that numbers that are exactly
787 halfway between two representations are always rounded
788 away from zero. This is not what sprintf normally does
789 (usually it rounds to even), so we have to fake it as
790 best we can, by formatting with extra precision and then
791 doing the rounding ourselves.
793 We take up to two rounds to format numbers. In the
794 first round, we obtain 2 digits of precision beyond
795 those requested by the user. If those digits are
796 exactly "50", then in a second round we format with as
797 many digits as are significant in a "double".
799 It might be better to directly implement our own
800 floating-point formatting routine instead of relying on
801 the system's sprintf implementation. But the classic
802 Steele and White paper on printing floating-point
803 numbers does not hint how to do what we want, and it's
804 not obvious how to change their algorithms to do so. It
805 would also be a lot of work. */
806 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
807 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
809 int binary_exponent, decimal_exponent, format_decimals;
810 frexp (number, &binary_exponent);
811 decimal_exponent = binary_exponent * 3 / 10;
812 format_decimals = (DBL_DIG + 1) - decimal_exponent;
813 if (format_decimals > max_decimals + 2)
814 sprintf (r->string, "%.*f", format_decimals, fabs (number));
818 if (r->string[0] == '0')
819 memmove (r->string, &r->string[1], strlen (r->string));
821 r->leading_zeros = strspn (r->string, "0.");
822 r->leading_nines = strspn (r->string, "9.");
823 r->integer_digits = strchr (r->string, '.') - r->string;
824 r->negative = number < 0;
827 /* Returns the number of characters required to format the
828 magnitude represented by R to DECIMALS decimal places.
829 The return value includes integer digits and a decimal point
830 and fractional digits, if any, but it does not include any
831 negative prefix or suffix or other affixes.
833 *INTEGER_DIGITS is set to the number of digits before the
834 decimal point in the output, between 0 and 40.
836 If R represents a negative number and its rounded
837 representation would include at least one nonzero digit,
838 *NEGATIVE is set to true; otherwise, it is set to false. */
840 rounder_width (const struct rounder *r, int decimals,
841 int *integer_digits, bool *negative)
843 /* Calculate base measures. */
844 int width = r->integer_digits;
846 width += decimals + 1;
847 *integer_digits = r->integer_digits;
848 *negative = r->negative;
850 /* Rounding can cause adjustments. */
851 if (should_round_up (r, decimals))
853 /* Rounding up leading 9s adds a new digit (a 1). */
854 if (r->leading_nines >= width)
863 if (r->leading_zeros >= width)
865 /* All digits that remain after rounding are zeros.
866 Therefore we drop the negative sign. */
868 if (r->integer_digits == 0 && decimals == 0)
870 /* No digits at all are left. We need to display
871 at least a single digit (a zero). */
881 /* Formats the magnitude represented by R into OUTPUT, rounding
882 to DECIMALS decimal places. Exactly as many characters as
883 indicated by rounder_width are written. No terminating null
886 rounder_format (const struct rounder *r, int decimals, char *output)
888 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
889 if (should_round_up (r, decimals))
891 if (r->leading_nines < base_width)
893 /* Rounding up. This is the common case where rounding
894 up doesn't add an extra digit. */
896 memcpy (output, r->string, base_width);
897 for (p = output + base_width - 1; ; p--)
899 assert (p >= output);
902 else if (*p >= '0' && *p <= '8')
913 /* Rounding up leading 9s causes the result to be a 1
914 followed by a number of 0s, plus a decimal point. */
917 p = mempset (p, '0', r->integer_digits);
921 p = mempset (p, '0', decimals);
923 assert (p == output + base_width + 1);
929 if (r->integer_digits != 0 || decimals != 0)
931 /* Common case: just copy the digits. */
932 memcpy (output, r->string, base_width);
936 /* No digits remain. The output is just a zero. */
942 /* Helper functions. */
945 static double PURE_FUNCTION
948 static const double p[] =
950 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
951 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
952 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
953 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
956 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
959 /* Returns 256**X. */
960 static double PURE_FUNCTION
963 static const double p[] =
973 18446744073709551616.0
975 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
978 /* Formats non-finite NUMBER into OUTPUT according to the width
981 output_infinite (double number, const struct fmt_spec *format, char *output)
983 assert (!isfinite (number));
991 else if (isinf (number))
992 s = number > 0 ? "+Infinity" : "-Infinity";
996 buf_copy_str_lpad (output, format->w, s, ' ');
999 output_overflow (format, output);
1001 output[format->w] = '\0';
1004 /* Formats OUTPUT as a missing value for the given FORMAT. */
1006 output_missing (const struct fmt_spec *format, char *output)
1008 memset (output, ' ', format->w);
1010 if (format->type != FMT_N)
1012 int dot_ofs = (format->type == FMT_PCT ? 2
1013 : format->type == FMT_E ? 5
1015 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
1018 output[format->w - 1] = '.';
1020 output[format->w] = '\0';
1023 /* Formats OUTPUT for overflow given FORMAT. */
1025 output_overflow (const struct fmt_spec *format, char *output)
1027 memset (output, '*', format->w);
1028 output[format->w] = '\0';
1031 /* Converts the integer part of NUMBER to a packed BCD number
1032 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
1033 the least significant nibble of the final byte in OUTPUT is
1034 set to 0. Returns true if successful, false if NUMBER is not
1035 representable. On failure, OUTPUT is cleared to all zero
1038 output_bcd_integer (double number, int digits, char *output)
1042 assert (digits < sizeof decimal);
1044 output[DIV_RND_UP (digits, 2)] = '\0';
1045 if (number != SYSMIS
1047 && number < power10 (digits)
1048 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1050 const char *src = decimal;
1053 for (i = 0; i < digits / 2; i++)
1055 int d0 = *src++ - '0';
1056 int d1 = *src++ - '0';
1057 *output++ = (d0 << 4) + d1;
1060 *output = (*src - '0') << 4;
1066 memset (output, 0, DIV_RND_UP (digits, 2));
1071 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1072 given INTEGER_FORMAT. */
1074 output_binary_integer (uint64_t value, int bytes,
1075 enum integer_format integer_format, char *output)
1077 integer_put (value, integer_format, output, bytes);
1080 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1081 digits in OUTPUT. */
1083 output_hex (const void *data_, size_t bytes, char *output)
1085 const uint8_t *data = data_;
1088 for (i = 0; i < bytes; i++)
1090 static const char hex_digits[] = "0123456789ABCDEF";
1091 *output++ = hex_digits[data[i] >> 4];
1092 *output++ = hex_digits[data[i] & 15];