1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2009 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, LEGACY_NATIVE)
108 && fmt_get_category (format->type) != FMT_CAT_BINARY)
109 legacy_recode (LEGACY_NATIVE, output, encoding, output, format->w);
112 /* Converts the INPUT value into a UTF8 encoded string, according to format
113 specification FORMAT.
115 VALUE must be the correct width for FORMAT, that is, its
116 width must be fmt_var_width(FORMAT).
118 The return value is dynamically allocated, and must be freed
119 by the caller. If POOL is non-null, then the return value is
120 allocated on that pool.
123 data_out_pool (const union value *input, const char *encoding, const struct fmt_spec *format,
126 char *output = xmalloc (format->w + 1);
128 assert (fmt_check_output (format));
130 converters[format->type] (input, format, output);
131 output[format->w] = '\0';
133 t = recode_string_pool (UTF8, encoding, output, format->w, pool);
139 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
141 return data_out_pool (input, encoding, format, NULL);
145 /* Main conversion functions. */
147 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
150 output_number (const union value *input, const struct fmt_spec *format,
153 double number = input->f;
155 if (number == SYSMIS)
156 output_missing (format, output);
157 else if (!isfinite (number))
158 output_infinite (number, format, output);
161 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
164 rounder_init (&r, number, format->d);
166 if (output_decimal (&r, format, true, output)
167 || output_scientific (number, format, true, output)
168 || output_decimal (&r, format, false, output))
172 if (!output_scientific (number, format, false, output))
173 output_overflow (format, output);
177 /* Outputs N format. */
179 output_N (const union value *input, const struct fmt_spec *format,
182 double number = input->f * power10 (format->d);
183 if (input->f == SYSMIS || number < 0)
184 output_missing (format, output);
188 number = fabs (round (number));
189 if (number < power10 (format->w)
190 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
191 memcpy (output, buf, format->w);
193 output_overflow (format, output);
197 /* Outputs Z format. */
199 output_Z (const union value *input, const struct fmt_spec *format,
202 double number = input->f * power10 (format->d);
204 if (input->f == SYSMIS)
205 output_missing (format, output);
206 else if (fabs (number) >= power10 (format->w)
207 || sprintf (buf, "%0*.0f", format->w,
208 fabs (round (number))) != format->w)
209 output_overflow (format, output);
212 if (number < 0 && strspn (buf, "0") < format->w)
214 char *p = &buf[format->w - 1];
215 *p = "}JKLMNOPQR"[*p - '0'];
217 memcpy (output, buf, format->w);
221 /* Outputs P format. */
223 output_P (const union value *input, const struct fmt_spec *format,
226 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
227 format->w * 2 - 1, output)
229 output[format->w - 1] |= 0xd;
231 output[format->w - 1] |= 0xf;
234 /* Outputs PK format. */
236 output_PK (const union value *input, const struct fmt_spec *format,
239 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
242 /* Outputs IB format. */
244 output_IB (const union value *input, const struct fmt_spec *format,
247 double number = round (input->f * power10 (format->d));
248 if (input->f == SYSMIS
249 || number >= power256 (format->w) / 2 - 1
250 || number < -power256 (format->w) / 2)
251 memset (output, 0, format->w);
254 uint64_t integer = fabs (number);
257 output_binary_integer (integer, format->w,
258 settings_get_output_integer_format (),
263 /* Outputs PIB format. */
265 output_PIB (const union value *input, const struct fmt_spec *format,
268 double number = round (input->f * power10 (format->d));
269 if (input->f == SYSMIS
270 || number < 0 || number >= power256 (format->w))
271 memset (output, 0, format->w);
273 output_binary_integer (number, format->w,
274 settings_get_output_integer_format (), output);
277 /* Outputs PIBHEX format. */
279 output_PIBHEX (const union value *input, const struct fmt_spec *format,
282 double number = round (input->f);
283 if (input->f == SYSMIS)
284 output_missing (format, output);
285 else if (input->f < 0 || number >= power256 (format->w / 2))
286 output_overflow (format, output);
290 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
291 output_hex (tmp, format->w / 2, output);
295 /* Outputs RB format. */
297 output_RB (const union value *input, const struct fmt_spec *format,
301 memcpy (output, &d, format->w);
304 /* Outputs RBHEX format. */
306 output_RBHEX (const union value *input, const struct fmt_spec *format,
310 output_hex (&d, format->w / 2, output);
313 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
314 DATETIME, TIME, and DTIME formats. */
316 output_date (const union value *input, const struct fmt_spec *format,
319 double number = input->f;
320 int year, month, day, yday;
322 const char *template = fmt_date_template (format->type);
323 size_t template_width = strlen (template);
324 int excess_width = format->w - template_width;
329 assert (format->w >= template_width);
330 if (number == SYSMIS)
333 if (fmt_get_category (format->type) == FMT_CAT_DATE)
337 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
338 &year, &month, &day, &yday);
339 number = fmod (number, 60. * 60. * 24.);
342 year = month = day = yday = 0;
344 while (*template != '\0')
348 while (template[count] == ch)
356 p += sprintf (p, "%02d", day);
358 p += sprintf (p, "%03d", yday);
362 p += sprintf (p, "%02d", month);
365 static const char *const months[12] =
367 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
368 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
370 p = stpcpy (p, months[month - 1]);
374 if (count >= 4 || excess_width >= 2)
377 p += sprintf (p, "%04d", year);
378 else if (format->type == FMT_DATETIME)
379 p = stpcpy (p, "****");
385 int epoch = settings_get_epoch ();
386 int offset = year - epoch;
387 if (offset < 0 || offset > 99)
389 p += sprintf (p, "%02d", abs (year) % 100);
393 p += sprintf (p, "%d", (month - 1) / 3 + 1);
396 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
401 number = fabs (number);
402 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
403 number = fmod (number, 60. * 60. * 24.);
408 number = fabs (number);
409 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
410 number = fmod (number, 60. * 60.);
413 p += sprintf (p, "%02d", (int) floor (number / 60.));
414 number = fmod (number, 60.);
415 excess_width = format->w - (p - tmp);
416 if (excess_width < 0)
418 if (excess_width == 3 || excess_width == 4
419 || (excess_width >= 5 && format->d == 0))
420 p += sprintf (p, ":%02d", (int) number);
421 else if (excess_width >= 5)
423 int d = MIN (format->d, excess_width - 4);
425 sprintf (p, ":%0*.*f", w, d, number);
426 if (settings_get_decimal_char (FMT_F) != '.')
428 char *cp = strchr (p, '.');
430 *cp = settings_get_decimal_char (FMT_F);
445 buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
449 output_overflow (format, output);
453 output_missing (format, output);
457 /* Outputs WKDAY format. */
459 output_WKDAY (const union value *input, const struct fmt_spec *format,
462 static const char *const weekdays[7] =
464 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
465 "THURSDAY", "FRIDAY", "SATURDAY",
468 if (input->f >= 1 && input->f < 8)
469 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1], ' ');
472 if (input->f != SYSMIS)
473 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
474 output_missing (format, output);
478 /* Outputs MONTH format. */
480 output_MONTH (const union value *input, const struct fmt_spec *format,
483 static const char *const months[12] =
485 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
486 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
489 if (input->f >= 1 && input->f < 13)
490 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
493 if (input->f != SYSMIS)
494 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
495 output_missing (format, output);
499 /* Outputs A format. */
501 output_A (const union value *input, const struct fmt_spec *format,
504 memcpy (output, value_str (input, format->w), format->w);
507 /* Outputs AHEX format. */
509 output_AHEX (const union value *input, const struct fmt_spec *format,
512 output_hex (value_str (input, format->w), format->w / 2, output);
515 /* Decimal and scientific formatting. */
517 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
518 increments *WIDTH by REQUEST and return true.
519 Otherwise returns false without changing *WIDTH. */
521 allocate_space (int request, int max_width, int *width)
523 assert (*width <= max_width);
524 if (request + *width <= max_width)
533 /* Tries to compose the number represented by R, in the style of
534 FORMAT, into OUTPUT. Returns true if successful, false on
535 failure, which occurs if FORMAT's width is too narrow. If
536 REQUIRE_AFFIXES is true, then the prefix and suffix specified
537 by FORMAT's style must be included; otherwise, they may be
538 omitted to make the number fit. */
540 output_decimal (const struct rounder *r, const struct fmt_spec *format,
541 bool require_affixes, char *output)
543 const struct fmt_number_style *style =
544 settings_get_style (format->type);
548 for (decimals = format->d; decimals >= 0; decimals--)
550 /* Formatted version of magnitude of NUMBER. */
553 /* Number of digits in MAGNITUDE's integer and fractional parts. */
556 /* Amount of space within the field width already claimed.
557 Initially this is the width of MAGNITUDE, then it is reduced
558 in stages as space is allocated to prefixes and suffixes and
559 grouping characters. */
562 /* Include various decorations? */
567 /* Position in output. */
570 /* Make sure there's room for the number's magnitude, plus
571 the negative suffix, plus (if negative) the negative
573 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
574 width += ss_length (style->neg_suffix);
576 width += ss_length (style->neg_prefix);
577 if (width > format->w)
580 /* If there's room for the prefix and suffix, allocate
581 space. If the affixes are required, but there's no
583 add_affixes = allocate_space (fmt_affix_width (style),
585 if (!add_affixes && require_affixes)
588 /* Check whether we should include grouping characters.
589 We need room for a complete set or we don't insert any at all.
590 We don't include grouping characters if decimal places were
591 requested but they were all dropped. */
592 add_grouping = (style->grouping != 0
593 && integer_digits > 3
594 && (format->d == 0 || decimals > 0)
595 && allocate_space ((integer_digits - 1) / 3,
598 /* Format the number's magnitude. */
599 rounder_format (r, decimals, magnitude);
601 /* Assemble number. */
603 if (format->w > width)
604 p = mempset (p, ' ', format->w - width);
606 p = mempcpy (p, ss_data (style->neg_prefix),
607 ss_length (style->neg_prefix));
609 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
611 p = mempcpy (p, magnitude, integer_digits);
615 for (i = 0; i < integer_digits; i++)
617 if (i > 0 && (integer_digits - i) % 3 == 0)
618 *p++ = style->grouping;
624 *p++ = style->decimal;
625 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
628 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
630 p = mempcpy (p, ss_data (style->neg_suffix),
631 ss_length (style->neg_suffix));
633 p = mempset (p, ' ', ss_length (style->neg_suffix));
634 assert (p == output + format->w);
641 /* Formats NUMBER into OUTPUT in scientific notation according to
642 the style of the format specified in FORMAT. */
644 output_scientific (double number, const struct fmt_spec *format,
645 bool require_affixes, char *output)
647 const struct fmt_number_style *style =
648 settings_get_style (format->type);
654 /* Allocate minimum required space. */
655 width = 6 + ss_length (style->neg_suffix);
657 width += ss_length (style->neg_prefix);
658 if (width > format->w)
661 /* Check for room for prefix and suffix. */
662 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
663 if (require_affixes && !add_affixes)
666 /* Figure out number of characters we can use for the fraction,
667 if any. (If that turns out to be 1, then we'll output a
668 decimal point without any digits following; that's what the
669 # flag does in the call to sprintf, below.) */
670 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
671 if (format->type != FMT_E && fraction_width == 1)
673 width += fraction_width;
675 /* Format (except suffix). */
677 if (width < format->w)
678 p = mempset (p, ' ', format->w - width);
680 p = mempcpy (p, ss_data (style->neg_prefix),
681 ss_length (style->neg_prefix));
683 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
684 if (fraction_width > 0)
685 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
687 sprintf (p, "%.0E", fabs (number));
689 /* The C locale always uses a period `.' as a decimal point.
690 Translate to comma if necessary. */
691 if (style->decimal != '.')
693 char *cp = strchr (p, '.');
695 *cp = style->decimal;
698 /* Make exponent have exactly three digits, plus sign. */
700 char *cp = strchr (p, 'E') + 1;
701 long int exponent = strtol (cp, NULL, 10);
702 if (abs (exponent) > 999)
704 sprintf (cp, "%+04ld", exponent);
708 p = strchr (p, '\0');
710 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
712 p = mempcpy (p, ss_data (style->neg_suffix),
713 ss_length (style->neg_suffix));
715 p = mempset (p, ' ', ss_length (style->neg_suffix));
717 assert (p == buf + format->w);
718 memcpy (output, buf, format->w);
723 /* Returns true if the magnitude represented by R should be
724 rounded up when chopped off at DECIMALS decimal places, false
725 if it should be rounded down. */
727 should_round_up (const struct rounder *r, int decimals)
729 int digit = r->string[r->integer_digits + decimals + 1];
730 assert (digit >= '0' && digit <= '9');
734 /* Initializes R for formatting the magnitude of NUMBER to no
735 more than MAX_DECIMAL decimal places. */
737 rounder_init (struct rounder *r, double number, int max_decimals)
739 assert (fabs (number) < 1e41);
740 assert (max_decimals >= 0 && max_decimals <= 16);
741 if (max_decimals == 0)
743 /* Fast path. No rounding needed.
745 We append ".00" to the integer representation because
746 round_up assumes that fractional digits are present. */
747 sprintf (r->string, "%.0f.00", fabs (round (number)));
753 This is more difficult than it really should be because
754 we have to make sure that numbers that are exactly
755 halfway between two representations are always rounded
756 away from zero. This is not what sprintf normally does
757 (usually it rounds to even), so we have to fake it as
758 best we can, by formatting with extra precision and then
759 doing the rounding ourselves.
761 We take up to two rounds to format numbers. In the
762 first round, we obtain 2 digits of precision beyond
763 those requested by the user. If those digits are
764 exactly "50", then in a second round we format with as
765 many digits as are significant in a "double".
767 It might be better to directly implement our own
768 floating-point formatting routine instead of relying on
769 the system's sprintf implementation. But the classic
770 Steele and White paper on printing floating-point
771 numbers does not hint how to do what we want, and it's
772 not obvious how to change their algorithms to do so. It
773 would also be a lot of work. */
774 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
775 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
777 int binary_exponent, decimal_exponent, format_decimals;
778 frexp (number, &binary_exponent);
779 decimal_exponent = binary_exponent * 3 / 10;
780 format_decimals = (DBL_DIG + 1) - decimal_exponent;
781 if (format_decimals > max_decimals + 2)
782 sprintf (r->string, "%.*f", format_decimals, fabs (number));
786 if (r->string[0] == '0')
787 memmove (r->string, &r->string[1], strlen (r->string));
789 r->leading_zeros = strspn (r->string, "0.");
790 r->leading_nines = strspn (r->string, "9.");
791 r->integer_digits = strchr (r->string, '.') - r->string;
792 r->negative = number < 0;
795 /* Returns the number of characters required to format the
796 magnitude represented by R to DECIMALS decimal places.
797 The return value includes integer digits and a decimal point
798 and fractional digits, if any, but it does not include any
799 negative prefix or suffix or other affixes.
801 *INTEGER_DIGITS is set to the number of digits before the
802 decimal point in the output, between 0 and 40.
804 If R represents a negative number and its rounded
805 representation would include at least one nonzero digit,
806 *NEGATIVE is set to true; otherwise, it is set to false. */
808 rounder_width (const struct rounder *r, int decimals,
809 int *integer_digits, bool *negative)
811 /* Calculate base measures. */
812 int width = r->integer_digits;
814 width += decimals + 1;
815 *integer_digits = r->integer_digits;
816 *negative = r->negative;
818 /* Rounding can cause adjustments. */
819 if (should_round_up (r, decimals))
821 /* Rounding up leading 9s adds a new digit (a 1). */
822 if (r->leading_nines >= width)
831 if (r->leading_zeros >= width)
833 /* All digits that remain after rounding are zeros.
834 Therefore we drop the negative sign. */
836 if (r->integer_digits == 0 && decimals == 0)
838 /* No digits at all are left. We need to display
839 at least a single digit (a zero). */
849 /* Formats the magnitude represented by R into OUTPUT, rounding
850 to DECIMALS decimal places. Exactly as many characters as
851 indicated by rounder_width are written. No terminating null
854 rounder_format (const struct rounder *r, int decimals, char *output)
856 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
857 if (should_round_up (r, decimals))
859 if (r->leading_nines < base_width)
861 /* Rounding up. This is the common case where rounding
862 up doesn't add an extra digit. */
864 memcpy (output, r->string, base_width);
865 for (p = output + base_width - 1; ; p--)
867 assert (p >= output);
870 else if (*p >= '0' && *p <= '8')
881 /* Rounding up leading 9s causes the result to be a 1
882 followed by a number of 0s, plus a decimal point. */
885 p = mempset (p, '0', r->integer_digits);
889 p = mempset (p, '0', decimals);
891 assert (p == output + base_width + 1);
897 if (r->integer_digits != 0 || decimals != 0)
899 /* Common case: just copy the digits. */
900 memcpy (output, r->string, base_width);
904 /* No digits remain. The output is just a zero. */
910 /* Helper functions. */
913 static double PURE_FUNCTION
916 static const double p[] =
918 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
919 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
920 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
921 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
924 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
927 /* Returns 256**X. */
928 static double PURE_FUNCTION
931 static const double p[] =
941 18446744073709551616.0
943 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
946 /* Formats non-finite NUMBER into OUTPUT according to the width
949 output_infinite (double number, const struct fmt_spec *format, char *output)
951 assert (!isfinite (number));
959 else if (isinf (number))
960 s = number > 0 ? "+Infinity" : "-Infinity";
964 buf_copy_str_lpad (output, format->w, s, ' ');
967 output_overflow (format, output);
970 /* Formats OUTPUT as a missing value for the given FORMAT. */
972 output_missing (const struct fmt_spec *format, char *output)
974 memset (output, ' ', format->w);
976 if (format->type != FMT_N)
978 int dot_ofs = (format->type == FMT_PCT ? 2
979 : format->type == FMT_E ? 5
981 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
984 output[format->w - 1] = '.';
987 /* Formats OUTPUT for overflow given FORMAT. */
989 output_overflow (const struct fmt_spec *format, char *output)
991 memset (output, '*', format->w);
994 /* Converts the integer part of NUMBER to a packed BCD number
995 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
996 the least significant nibble of the final byte in OUTPUT is
997 set to 0. Returns true if successful, false if NUMBER is not
998 representable. On failure, OUTPUT is cleared to all zero
1001 output_bcd_integer (double number, int digits, char *output)
1005 assert (digits < sizeof decimal);
1006 if (number != SYSMIS
1008 && number < power10 (digits)
1009 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1011 const char *src = decimal;
1014 for (i = 0; i < digits / 2; i++)
1016 int d0 = *src++ - '0';
1017 int d1 = *src++ - '0';
1018 *output++ = (d0 << 4) + d1;
1021 *output = (*src - '0') << 4;
1027 memset (output, 0, DIV_RND_UP (digits, 2));
1032 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1033 given INTEGER_FORMAT. */
1035 output_binary_integer (uint64_t value, int bytes,
1036 enum integer_format integer_format, char *output)
1038 integer_put (value, integer_format, output, bytes);
1041 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1042 digits in OUTPUT. */
1044 output_hex (const void *data_, size_t bytes, char *output)
1046 const uint8_t *data = data_;
1049 for (i = 0; i < bytes; i++)
1051 static const char hex_digits[] = "0123456789ABCDEF";
1052 *output++ = hex_digits[data[i] >> 4];
1053 *output++ = hex_digits[data[i] & 15];