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)
110 char *s = recode_string (encoding, LEGACY_NATIVE, output, format->w );
111 memcpy (output, s, format->w);
116 /* Converts the INPUT value into a UTF8 encoded string, according to format
117 specification FORMAT.
119 VALUE must be the correct width for FORMAT, that is, its
120 width must be fmt_var_width(FORMAT).
122 The return value is dynamically allocated, and must be freed
123 by the caller. If POOL is non-null, then the return value is
124 allocated on that pool.
127 data_out_pool (const union value *input, const char *encoding, const struct fmt_spec *format,
130 char *output = xmalloc (format->w + 1);
132 assert (fmt_check_output (format));
134 converters[format->type] (input, format, output);
135 output[format->w] = '\0';
137 t = recode_string_pool (UTF8, encoding, output, format->w, pool);
143 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
145 return data_out_pool (input, encoding, format, NULL);
149 /* Main conversion functions. */
151 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
154 output_number (const union value *input, const struct fmt_spec *format,
157 double number = input->f;
159 if (number == SYSMIS)
160 output_missing (format, output);
161 else if (!isfinite (number))
162 output_infinite (number, format, output);
165 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
168 rounder_init (&r, number, format->d);
170 if (output_decimal (&r, format, true, output)
171 || output_scientific (number, format, true, output)
172 || output_decimal (&r, format, false, output))
176 if (!output_scientific (number, format, false, output))
177 output_overflow (format, output);
181 /* Outputs N format. */
183 output_N (const union value *input, const struct fmt_spec *format,
186 double number = input->f * power10 (format->d);
187 if (input->f == SYSMIS || number < 0)
188 output_missing (format, output);
192 number = fabs (round (number));
193 if (number < power10 (format->w)
194 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
195 memcpy (output, buf, format->w);
197 output_overflow (format, output);
201 /* Outputs Z format. */
203 output_Z (const union value *input, const struct fmt_spec *format,
206 double number = input->f * power10 (format->d);
208 if (input->f == SYSMIS)
209 output_missing (format, output);
210 else if (fabs (number) >= power10 (format->w)
211 || sprintf (buf, "%0*.0f", format->w,
212 fabs (round (number))) != format->w)
213 output_overflow (format, output);
216 if (number < 0 && strspn (buf, "0") < format->w)
218 char *p = &buf[format->w - 1];
219 *p = "}JKLMNOPQR"[*p - '0'];
221 memcpy (output, buf, format->w);
225 /* Outputs P format. */
227 output_P (const union value *input, const struct fmt_spec *format,
230 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
231 format->w * 2 - 1, output)
233 output[format->w - 1] |= 0xd;
235 output[format->w - 1] |= 0xf;
238 /* Outputs PK format. */
240 output_PK (const union value *input, const struct fmt_spec *format,
243 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
246 /* Outputs IB format. */
248 output_IB (const union value *input, const struct fmt_spec *format,
251 double number = round (input->f * power10 (format->d));
252 if (input->f == SYSMIS
253 || number >= power256 (format->w) / 2 - 1
254 || number < -power256 (format->w) / 2)
255 memset (output, 0, format->w);
258 uint64_t integer = fabs (number);
261 output_binary_integer (integer, format->w,
262 settings_get_output_integer_format (),
267 /* Outputs PIB format. */
269 output_PIB (const union value *input, const struct fmt_spec *format,
272 double number = round (input->f * power10 (format->d));
273 if (input->f == SYSMIS
274 || number < 0 || number >= power256 (format->w))
275 memset (output, 0, format->w);
277 output_binary_integer (number, format->w,
278 settings_get_output_integer_format (), output);
281 /* Outputs PIBHEX format. */
283 output_PIBHEX (const union value *input, const struct fmt_spec *format,
286 double number = round (input->f);
287 if (input->f == SYSMIS)
288 output_missing (format, output);
289 else if (input->f < 0 || number >= power256 (format->w / 2))
290 output_overflow (format, output);
294 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
295 output_hex (tmp, format->w / 2, output);
299 /* Outputs RB format. */
301 output_RB (const union value *input, const struct fmt_spec *format,
305 memcpy (output, &d, format->w);
308 /* Outputs RBHEX format. */
310 output_RBHEX (const union value *input, const struct fmt_spec *format,
314 output_hex (&d, format->w / 2, output);
317 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
318 DATETIME, TIME, and DTIME formats. */
320 output_date (const union value *input, const struct fmt_spec *format,
323 double number = input->f;
324 int year, month, day, yday;
326 const char *template = fmt_date_template (format->type);
327 size_t template_width = strlen (template);
328 int excess_width = format->w - template_width;
333 assert (format->w >= template_width);
334 if (number == SYSMIS)
337 if (fmt_get_category (format->type) == FMT_CAT_DATE)
341 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
342 &year, &month, &day, &yday);
343 number = fmod (number, 60. * 60. * 24.);
346 year = month = day = yday = 0;
348 while (*template != '\0')
352 while (template[count] == ch)
360 p += sprintf (p, "%02d", day);
362 p += sprintf (p, "%03d", yday);
366 p += sprintf (p, "%02d", month);
369 static const char *const months[12] =
371 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
372 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
374 p = stpcpy (p, months[month - 1]);
378 if (count >= 4 || excess_width >= 2)
381 p += sprintf (p, "%04d", year);
382 else if (format->type == FMT_DATETIME)
383 p = stpcpy (p, "****");
389 int epoch = settings_get_epoch ();
390 int offset = year - epoch;
391 if (offset < 0 || offset > 99)
393 p += sprintf (p, "%02d", abs (year) % 100);
397 p += sprintf (p, "%d", (month - 1) / 3 + 1);
400 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
405 number = fabs (number);
406 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
407 number = fmod (number, 60. * 60. * 24.);
412 number = fabs (number);
413 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
414 number = fmod (number, 60. * 60.);
417 p += sprintf (p, "%02d", (int) floor (number / 60.));
418 number = fmod (number, 60.);
419 excess_width = format->w - (p - tmp);
420 if (excess_width < 0)
422 if (excess_width == 3 || excess_width == 4
423 || (excess_width >= 5 && format->d == 0))
424 p += sprintf (p, ":%02d", (int) number);
425 else if (excess_width >= 5)
427 int d = MIN (format->d, excess_width - 4);
429 sprintf (p, ":%0*.*f", w, d, number);
430 if (settings_get_decimal_char (FMT_F) != '.')
432 char *cp = strchr (p, '.');
434 *cp = settings_get_decimal_char (FMT_F);
449 buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
453 output_overflow (format, output);
457 output_missing (format, output);
461 /* Outputs WKDAY format. */
463 output_WKDAY (const union value *input, const struct fmt_spec *format,
466 static const char *const weekdays[7] =
468 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
469 "THURSDAY", "FRIDAY", "SATURDAY",
472 if (input->f >= 1 && input->f < 8)
473 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1], ' ');
476 if (input->f != SYSMIS)
477 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
478 output_missing (format, output);
482 /* Outputs MONTH format. */
484 output_MONTH (const union value *input, const struct fmt_spec *format,
487 static const char *const months[12] =
489 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
490 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
493 if (input->f >= 1 && input->f < 13)
494 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
497 if (input->f != SYSMIS)
498 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
499 output_missing (format, output);
503 /* Outputs A format. */
505 output_A (const union value *input, const struct fmt_spec *format,
508 memcpy (output, value_str (input, format->w), format->w);
511 /* Outputs AHEX format. */
513 output_AHEX (const union value *input, const struct fmt_spec *format,
516 output_hex (value_str (input, format->w), format->w / 2, output);
519 /* Decimal and scientific formatting. */
521 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
522 increments *WIDTH by REQUEST and return true.
523 Otherwise returns false without changing *WIDTH. */
525 allocate_space (int request, int max_width, int *width)
527 assert (*width <= max_width);
528 if (request + *width <= max_width)
537 /* Tries to compose the number represented by R, in the style of
538 FORMAT, into OUTPUT. Returns true if successful, false on
539 failure, which occurs if FORMAT's width is too narrow. If
540 REQUIRE_AFFIXES is true, then the prefix and suffix specified
541 by FORMAT's style must be included; otherwise, they may be
542 omitted to make the number fit. */
544 output_decimal (const struct rounder *r, const struct fmt_spec *format,
545 bool require_affixes, char *output)
547 const struct fmt_number_style *style =
548 settings_get_style (format->type);
552 for (decimals = format->d; decimals >= 0; decimals--)
554 /* Formatted version of magnitude of NUMBER. */
557 /* Number of digits in MAGNITUDE's integer and fractional parts. */
560 /* Amount of space within the field width already claimed.
561 Initially this is the width of MAGNITUDE, then it is reduced
562 in stages as space is allocated to prefixes and suffixes and
563 grouping characters. */
566 /* Include various decorations? */
571 /* Position in output. */
574 /* Make sure there's room for the number's magnitude, plus
575 the negative suffix, plus (if negative) the negative
577 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
578 width += ss_length (style->neg_suffix);
580 width += ss_length (style->neg_prefix);
581 if (width > format->w)
584 /* If there's room for the prefix and suffix, allocate
585 space. If the affixes are required, but there's no
587 add_affixes = allocate_space (fmt_affix_width (style),
589 if (!add_affixes && require_affixes)
592 /* Check whether we should include grouping characters.
593 We need room for a complete set or we don't insert any at all.
594 We don't include grouping characters if decimal places were
595 requested but they were all dropped. */
596 add_grouping = (style->grouping != 0
597 && integer_digits > 3
598 && (format->d == 0 || decimals > 0)
599 && allocate_space ((integer_digits - 1) / 3,
602 /* Format the number's magnitude. */
603 rounder_format (r, decimals, magnitude);
605 /* Assemble number. */
607 if (format->w > width)
608 p = mempset (p, ' ', format->w - width);
610 p = mempcpy (p, ss_data (style->neg_prefix),
611 ss_length (style->neg_prefix));
613 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
615 p = mempcpy (p, magnitude, integer_digits);
619 for (i = 0; i < integer_digits; i++)
621 if (i > 0 && (integer_digits - i) % 3 == 0)
622 *p++ = style->grouping;
628 *p++ = style->decimal;
629 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
632 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
634 p = mempcpy (p, ss_data (style->neg_suffix),
635 ss_length (style->neg_suffix));
637 p = mempset (p, ' ', ss_length (style->neg_suffix));
638 assert (p == output + format->w);
645 /* Formats NUMBER into OUTPUT in scientific notation according to
646 the style of the format specified in FORMAT. */
648 output_scientific (double number, const struct fmt_spec *format,
649 bool require_affixes, char *output)
651 const struct fmt_number_style *style =
652 settings_get_style (format->type);
658 /* Allocate minimum required space. */
659 width = 6 + ss_length (style->neg_suffix);
661 width += ss_length (style->neg_prefix);
662 if (width > format->w)
665 /* Check for room for prefix and suffix. */
666 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
667 if (require_affixes && !add_affixes)
670 /* Figure out number of characters we can use for the fraction,
671 if any. (If that turns out to be 1, then we'll output a
672 decimal point without any digits following; that's what the
673 # flag does in the call to sprintf, below.) */
674 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
675 if (format->type != FMT_E && fraction_width == 1)
677 width += fraction_width;
679 /* Format (except suffix). */
681 if (width < format->w)
682 p = mempset (p, ' ', format->w - width);
684 p = mempcpy (p, ss_data (style->neg_prefix),
685 ss_length (style->neg_prefix));
687 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
688 if (fraction_width > 0)
689 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
691 sprintf (p, "%.0E", fabs (number));
693 /* The C locale always uses a period `.' as a decimal point.
694 Translate to comma if necessary. */
695 if (style->decimal != '.')
697 char *cp = strchr (p, '.');
699 *cp = style->decimal;
702 /* Make exponent have exactly three digits, plus sign. */
704 char *cp = strchr (p, 'E') + 1;
705 long int exponent = strtol (cp, NULL, 10);
706 if (abs (exponent) > 999)
708 sprintf (cp, "%+04ld", exponent);
712 p = strchr (p, '\0');
714 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
716 p = mempcpy (p, ss_data (style->neg_suffix),
717 ss_length (style->neg_suffix));
719 p = mempset (p, ' ', ss_length (style->neg_suffix));
721 assert (p == buf + format->w);
722 memcpy (output, buf, format->w);
727 /* Returns true if the magnitude represented by R should be
728 rounded up when chopped off at DECIMALS decimal places, false
729 if it should be rounded down. */
731 should_round_up (const struct rounder *r, int decimals)
733 int digit = r->string[r->integer_digits + decimals + 1];
734 assert (digit >= '0' && digit <= '9');
738 /* Initializes R for formatting the magnitude of NUMBER to no
739 more than MAX_DECIMAL decimal places. */
741 rounder_init (struct rounder *r, double number, int max_decimals)
743 assert (fabs (number) < 1e41);
744 assert (max_decimals >= 0 && max_decimals <= 16);
745 if (max_decimals == 0)
747 /* Fast path. No rounding needed.
749 We append ".00" to the integer representation because
750 round_up assumes that fractional digits are present. */
751 sprintf (r->string, "%.0f.00", fabs (round (number)));
757 This is more difficult than it really should be because
758 we have to make sure that numbers that are exactly
759 halfway between two representations are always rounded
760 away from zero. This is not what sprintf normally does
761 (usually it rounds to even), so we have to fake it as
762 best we can, by formatting with extra precision and then
763 doing the rounding ourselves.
765 We take up to two rounds to format numbers. In the
766 first round, we obtain 2 digits of precision beyond
767 those requested by the user. If those digits are
768 exactly "50", then in a second round we format with as
769 many digits as are significant in a "double".
771 It might be better to directly implement our own
772 floating-point formatting routine instead of relying on
773 the system's sprintf implementation. But the classic
774 Steele and White paper on printing floating-point
775 numbers does not hint how to do what we want, and it's
776 not obvious how to change their algorithms to do so. It
777 would also be a lot of work. */
778 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
779 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
781 int binary_exponent, decimal_exponent, format_decimals;
782 frexp (number, &binary_exponent);
783 decimal_exponent = binary_exponent * 3 / 10;
784 format_decimals = (DBL_DIG + 1) - decimal_exponent;
785 if (format_decimals > max_decimals + 2)
786 sprintf (r->string, "%.*f", format_decimals, fabs (number));
790 if (r->string[0] == '0')
791 memmove (r->string, &r->string[1], strlen (r->string));
793 r->leading_zeros = strspn (r->string, "0.");
794 r->leading_nines = strspn (r->string, "9.");
795 r->integer_digits = strchr (r->string, '.') - r->string;
796 r->negative = number < 0;
799 /* Returns the number of characters required to format the
800 magnitude represented by R to DECIMALS decimal places.
801 The return value includes integer digits and a decimal point
802 and fractional digits, if any, but it does not include any
803 negative prefix or suffix or other affixes.
805 *INTEGER_DIGITS is set to the number of digits before the
806 decimal point in the output, between 0 and 40.
808 If R represents a negative number and its rounded
809 representation would include at least one nonzero digit,
810 *NEGATIVE is set to true; otherwise, it is set to false. */
812 rounder_width (const struct rounder *r, int decimals,
813 int *integer_digits, bool *negative)
815 /* Calculate base measures. */
816 int width = r->integer_digits;
818 width += decimals + 1;
819 *integer_digits = r->integer_digits;
820 *negative = r->negative;
822 /* Rounding can cause adjustments. */
823 if (should_round_up (r, decimals))
825 /* Rounding up leading 9s adds a new digit (a 1). */
826 if (r->leading_nines >= width)
835 if (r->leading_zeros >= width)
837 /* All digits that remain after rounding are zeros.
838 Therefore we drop the negative sign. */
840 if (r->integer_digits == 0 && decimals == 0)
842 /* No digits at all are left. We need to display
843 at least a single digit (a zero). */
853 /* Formats the magnitude represented by R into OUTPUT, rounding
854 to DECIMALS decimal places. Exactly as many characters as
855 indicated by rounder_width are written. No terminating null
858 rounder_format (const struct rounder *r, int decimals, char *output)
860 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
861 if (should_round_up (r, decimals))
863 if (r->leading_nines < base_width)
865 /* Rounding up. This is the common case where rounding
866 up doesn't add an extra digit. */
868 memcpy (output, r->string, base_width);
869 for (p = output + base_width - 1; ; p--)
871 assert (p >= output);
874 else if (*p >= '0' && *p <= '8')
885 /* Rounding up leading 9s causes the result to be a 1
886 followed by a number of 0s, plus a decimal point. */
889 p = mempset (p, '0', r->integer_digits);
893 p = mempset (p, '0', decimals);
895 assert (p == output + base_width + 1);
901 if (r->integer_digits != 0 || decimals != 0)
903 /* Common case: just copy the digits. */
904 memcpy (output, r->string, base_width);
908 /* No digits remain. The output is just a zero. */
914 /* Helper functions. */
917 static double PURE_FUNCTION
920 static const double p[] =
922 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
923 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
924 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
925 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
928 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
931 /* Returns 256**X. */
932 static double PURE_FUNCTION
935 static const double p[] =
945 18446744073709551616.0
947 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
950 /* Formats non-finite NUMBER into OUTPUT according to the width
953 output_infinite (double number, const struct fmt_spec *format, char *output)
955 assert (!isfinite (number));
963 else if (isinf (number))
964 s = number > 0 ? "+Infinity" : "-Infinity";
968 buf_copy_str_lpad (output, format->w, s, ' ');
971 output_overflow (format, output);
974 /* Formats OUTPUT as a missing value for the given FORMAT. */
976 output_missing (const struct fmt_spec *format, char *output)
978 memset (output, ' ', format->w);
980 if (format->type != FMT_N)
982 int dot_ofs = (format->type == FMT_PCT ? 2
983 : format->type == FMT_E ? 5
985 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
988 output[format->w - 1] = '.';
991 /* Formats OUTPUT for overflow given FORMAT. */
993 output_overflow (const struct fmt_spec *format, char *output)
995 memset (output, '*', format->w);
998 /* Converts the integer part of NUMBER to a packed BCD number
999 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
1000 the least significant nibble of the final byte in OUTPUT is
1001 set to 0. Returns true if successful, false if NUMBER is not
1002 representable. On failure, OUTPUT is cleared to all zero
1005 output_bcd_integer (double number, int digits, char *output)
1009 assert (digits < sizeof decimal);
1010 if (number != SYSMIS
1012 && number < power10 (digits)
1013 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1015 const char *src = decimal;
1018 for (i = 0; i < digits / 2; i++)
1020 int d0 = *src++ - '0';
1021 int d1 = *src++ - '0';
1022 *output++ = (d0 << 4) + d1;
1025 *output = (*src - '0') << 4;
1031 memset (output, 0, DIV_RND_UP (digits, 2));
1036 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1037 given INTEGER_FORMAT. */
1039 output_binary_integer (uint64_t value, int bytes,
1040 enum integer_format integer_format, char *output)
1042 integer_put (value, integer_format, output, bytes);
1045 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1046 digits in OUTPUT. */
1048 output_hex (const void *data_, size_t bytes, char *output)
1050 const uint8_t *data = data_;
1053 for (i = 0; i < bytes; i++)
1055 static const char hex_digits[] = "0123456789ABCDEF";
1056 *output++ = hex_digits[data[i] >> 4];
1057 *output++ = hex_digits[data[i] & 15];