1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006 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/>. */
23 #include <gsl/gsl_math.h>
29 #include <data/calendar.h>
30 #include <data/format.h>
31 #include <data/settings.h>
32 #include <data/value.h>
34 #include <libpspp/assertion.h>
35 #include <libpspp/float-format.h>
36 #include <libpspp/integer-format.h>
37 #include <libpspp/message.h>
38 #include <libpspp/misc.h>
39 #include <libpspp/str.h>
44 #define _(msgid) gettext (msgid)
46 /* A representation of a number that can be quickly rounded to
47 any desired number of decimal places (up to a specified
51 char string[64]; /* Magnitude of number with excess precision. */
52 int integer_digits; /* Number of digits before decimal point. */
53 int leading_nines; /* Number of `9's or `.'s at start of string. */
54 int leading_zeros; /* Number of `0's or `.'s at start of string. */
55 bool negative; /* Is the number negative? */
58 static void rounder_init (struct rounder *, double number, int max_decimals);
59 static int rounder_width (const struct rounder *, int decimals,
60 int *integer_digits, bool *negative);
61 static void rounder_format (const struct rounder *, int decimals,
64 typedef void data_out_converter_func (const union value *,
65 const struct fmt_spec *,
67 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
68 static data_out_converter_func output_##METHOD;
71 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
72 bool require_affixes, char *);
73 static bool output_scientific (double, const struct fmt_spec *,
74 bool require_affixes, char *);
76 static double power10 (int) PURE_FUNCTION;
77 static double power256 (int) PURE_FUNCTION;
79 static void output_infinite (double, const struct fmt_spec *, char *);
80 static void output_missing (const struct fmt_spec *, char *);
81 static void output_overflow (const struct fmt_spec *, char *);
82 static bool output_bcd_integer (double, int digits, char *);
83 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
85 static void output_hex (const void *, size_t bytes, char *);
87 /* Converts the INPUT value into printable form in the exactly
88 FORMAT->W characters in OUTPUT according to format
89 specification FORMAT. The output is recoded from native form
90 into the given legacy character ENCODING. No null terminator
91 is appended to the buffer. */
93 data_out_legacy (const union value *input, enum legacy_encoding encoding,
94 const struct fmt_spec *format, char *output)
96 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
98 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
102 assert (fmt_check_output (format));
104 converters[format->type] (input, format, output);
105 if (encoding != LEGACY_NATIVE
106 && fmt_get_category (format->type) != FMT_CAT_BINARY)
107 legacy_recode (LEGACY_NATIVE, output, encoding, output, format->w);
110 /* Same as data_out_legacy with ENCODING set to LEGACY_NATIVE. */
112 data_out (const union value *value, const struct fmt_spec *format,
115 return data_out_legacy (value, LEGACY_NATIVE, format, output);
119 /* Main conversion functions. */
121 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
124 output_number (const union value *input, const struct fmt_spec *format,
127 double number = input->f;
129 if (number == SYSMIS)
130 output_missing (format, output);
131 else if (!isfinite (number))
132 output_infinite (number, format, output);
135 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
138 rounder_init (&r, number, format->d);
140 if (output_decimal (&r, format, true, output)
141 || output_scientific (number, format, true, output)
142 || output_decimal (&r, format, false, output))
146 if (!output_scientific (number, format, false, output))
147 output_overflow (format, output);
151 /* Outputs N format. */
153 output_N (const union value *input, const struct fmt_spec *format,
156 double number = input->f * power10 (format->d);
157 if (input->f == SYSMIS || number < 0)
158 output_missing (format, output);
162 number = fabs (round (number));
163 if (number < power10 (format->w)
164 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
165 memcpy (output, buf, format->w);
167 output_overflow (format, output);
171 /* Outputs Z format. */
173 output_Z (const union value *input, const struct fmt_spec *format,
176 double number = input->f * power10 (format->d);
178 if (input->f == SYSMIS)
179 output_missing (format, output);
180 else if (fabs (number) >= power10 (format->w)
181 || sprintf (buf, "%0*.0f", format->w,
182 fabs (round (number))) != format->w)
183 output_overflow (format, output);
186 if (number < 0 && strspn (buf, "0") < format->w)
188 char *p = &buf[format->w - 1];
189 *p = "}JKLMNOPQR"[*p - '0'];
191 memcpy (output, buf, format->w);
195 /* Outputs P format. */
197 output_P (const union value *input, const struct fmt_spec *format,
200 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
201 format->w * 2 - 1, output)
203 output[format->w - 1] |= 0xd;
205 output[format->w - 1] |= 0xf;
208 /* Outputs PK format. */
210 output_PK (const union value *input, const struct fmt_spec *format,
213 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
216 /* Outputs IB format. */
218 output_IB (const union value *input, const struct fmt_spec *format,
221 double number = round (input->f * power10 (format->d));
222 if (input->f == SYSMIS
223 || number >= power256 (format->w) / 2 - 1
224 || number < -power256 (format->w) / 2)
225 memset (output, 0, format->w);
228 uint64_t integer = fabs (number);
231 output_binary_integer (integer, format->w,
232 settings_get_output_integer_format (),
237 /* Outputs PIB format. */
239 output_PIB (const union value *input, const struct fmt_spec *format,
242 double number = round (input->f * power10 (format->d));
243 if (input->f == SYSMIS
244 || number < 0 || number >= power256 (format->w))
245 memset (output, 0, format->w);
247 output_binary_integer (number, format->w,
248 settings_get_output_integer_format (), output);
251 /* Outputs PIBHEX format. */
253 output_PIBHEX (const union value *input, const struct fmt_spec *format,
256 double number = round (input->f);
257 if (input->f == SYSMIS)
258 output_missing (format, output);
259 else if (input->f < 0 || number >= power256 (format->w / 2))
260 output_overflow (format, output);
264 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
265 output_hex (tmp, format->w / 2, output);
269 /* Outputs RB format. */
271 output_RB (const union value *input, const struct fmt_spec *format,
275 memcpy (output, &d, format->w);
278 /* Outputs RBHEX format. */
280 output_RBHEX (const union value *input, const struct fmt_spec *format,
284 output_hex (&d, format->w / 2, output);
287 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
288 DATETIME, TIME, and DTIME formats. */
290 output_date (const union value *input, const struct fmt_spec *format,
293 double number = input->f;
294 int year, month, day, yday;
296 const char *template = fmt_date_template (format->type);
297 size_t template_width = strlen (template);
298 int excess_width = format->w - template_width;
303 assert (format->w >= template_width);
304 if (number == SYSMIS)
307 if (fmt_get_category (format->type) == FMT_CAT_DATE)
311 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
312 &year, &month, &day, &yday);
313 number = fmod (number, 60. * 60. * 24.);
316 year = month = day = yday = 0;
318 while (*template != '\0')
322 while (template[count] == ch)
330 p += sprintf (p, "%02d", day);
332 p += sprintf (p, "%03d", yday);
336 p += sprintf (p, "%02d", month);
339 static const char *const months[12] =
341 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
342 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
344 p = stpcpy (p, months[month - 1]);
348 if (count >= 4 || excess_width >= 2)
351 p += sprintf (p, "%04d", year);
352 else if (format->type == FMT_DATETIME)
353 p = stpcpy (p, "****");
359 int epoch = settings_get_epoch ();
360 int offset = year - epoch;
361 if (offset < 0 || offset > 99)
363 p += sprintf (p, "%02d", abs (year) % 100);
367 p += sprintf (p, "%d", (month - 1) / 3 + 1);
370 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
375 number = fabs (number);
376 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
377 number = fmod (number, 60. * 60. * 24.);
382 number = fabs (number);
383 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
384 number = fmod (number, 60. * 60.);
387 p += sprintf (p, "%02d", (int) floor (number / 60.));
388 number = fmod (number, 60.);
389 excess_width = format->w - (p - tmp);
390 if (excess_width < 0)
392 if (excess_width == 3 || excess_width == 4
393 || (excess_width >= 5 && format->d == 0))
394 p += sprintf (p, ":%02d", (int) number);
395 else if (excess_width >= 5)
397 int d = MIN (format->d, excess_width - 4);
399 sprintf (p, ":%0*.*f", w, d, number);
400 if (settings_get_decimal_char (FMT_F) != '.')
402 char *cp = strchr (p, '.');
404 *cp = settings_get_decimal_char (FMT_F);
419 buf_copy_lpad (output, format->w, tmp, p - tmp);
423 output_overflow (format, output);
427 output_missing (format, output);
431 /* Outputs WKDAY format. */
433 output_WKDAY (const union value *input, const struct fmt_spec *format,
436 static const char *const weekdays[7] =
438 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
439 "THURSDAY", "FRIDAY", "SATURDAY",
442 if (input->f >= 1 && input->f < 8)
443 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
446 if (input->f != SYSMIS)
447 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
448 output_missing (format, output);
452 /* Outputs MONTH format. */
454 output_MONTH (const union value *input, const struct fmt_spec *format,
457 static const char *const months[12] =
459 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
460 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
463 if (input->f >= 1 && input->f < 13)
464 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
467 if (input->f != SYSMIS)
468 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
469 output_missing (format, output);
473 /* Outputs A format. */
475 output_A (const union value *input, const struct fmt_spec *format,
478 memcpy (output, input->s, format->w);
481 /* Outputs AHEX format. */
483 output_AHEX (const union value *input, const struct fmt_spec *format,
486 output_hex (input->s, format->w / 2, output);
489 /* Decimal and scientific formatting. */
491 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
492 increments *WIDTH by REQUEST and return true.
493 Otherwise returns false without changing *WIDTH. */
495 allocate_space (int request, int max_width, int *width)
497 assert (*width <= max_width);
498 if (request + *width <= max_width)
507 /* Tries to compose the number represented by R, in the style of
508 FORMAT, into OUTPUT. Returns true if successful, false on
509 failure, which occurs if FORMAT's width is too narrow. If
510 REQUIRE_AFFIXES is true, then the prefix and suffix specified
511 by FORMAT's style must be included; otherwise, they may be
512 omitted to make the number fit. */
514 output_decimal (const struct rounder *r, const struct fmt_spec *format,
515 bool require_affixes, char *output)
517 const struct fmt_number_style *style =
518 settings_get_style (format->type);
522 for (decimals = format->d; decimals >= 0; decimals--)
524 /* Formatted version of magnitude of NUMBER. */
527 /* Number of digits in MAGNITUDE's integer and fractional parts. */
530 /* Amount of space within the field width already claimed.
531 Initially this is the width of MAGNITUDE, then it is reduced
532 in stages as space is allocated to prefixes and suffixes and
533 grouping characters. */
536 /* Include various decorations? */
541 /* Position in output. */
544 /* Make sure there's room for the number's magnitude, plus
545 the negative suffix, plus (if negative) the negative
547 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
548 width += ss_length (style->neg_suffix);
550 width += ss_length (style->neg_prefix);
551 if (width > format->w)
554 /* If there's room for the prefix and suffix, allocate
555 space. If the affixes are required, but there's no
557 add_affixes = allocate_space (fmt_affix_width (style),
559 if (!add_affixes && require_affixes)
562 /* Check whether we should include grouping characters.
563 We need room for a complete set or we don't insert any at all.
564 We don't include grouping characters if decimal places were
565 requested but they were all dropped. */
566 add_grouping = (style->grouping != 0
567 && integer_digits > 3
568 && (format->d == 0 || decimals > 0)
569 && allocate_space ((integer_digits - 1) / 3,
572 /* Format the number's magnitude. */
573 rounder_format (r, decimals, magnitude);
575 /* Assemble number. */
577 if (format->w > width)
578 p = mempset (p, ' ', format->w - width);
580 p = mempcpy (p, ss_data (style->neg_prefix),
581 ss_length (style->neg_prefix));
583 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
585 p = mempcpy (p, magnitude, integer_digits);
589 for (i = 0; i < integer_digits; i++)
591 if (i > 0 && (integer_digits - i) % 3 == 0)
592 *p++ = style->grouping;
598 *p++ = style->decimal;
599 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
602 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
604 p = mempcpy (p, ss_data (style->neg_suffix),
605 ss_length (style->neg_suffix));
607 p = mempset (p, ' ', ss_length (style->neg_suffix));
608 assert (p == output + format->w);
615 /* Formats NUMBER into OUTPUT in scientific notation according to
616 the style of the format specified in FORMAT. */
618 output_scientific (double number, const struct fmt_spec *format,
619 bool require_affixes, char *output)
621 const struct fmt_number_style *style =
622 settings_get_style (format->type);
628 /* Allocate minimum required space. */
629 width = 6 + ss_length (style->neg_suffix);
631 width += ss_length (style->neg_prefix);
632 if (width > format->w)
635 /* Check for room for prefix and suffix. */
636 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
637 if (require_affixes && !add_affixes)
640 /* Figure out number of characters we can use for the fraction,
641 if any. (If that turns out to be 1, then we'll output a
642 decimal point without any digits following; that's what the
643 # flag does in the call to sprintf, below.) */
644 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
645 if (format->type != FMT_E && fraction_width == 1)
647 width += fraction_width;
649 /* Format (except suffix). */
651 if (width < format->w)
652 p = mempset (p, ' ', format->w - width);
654 p = mempcpy (p, ss_data (style->neg_prefix),
655 ss_length (style->neg_prefix));
657 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
658 if (fraction_width > 0)
659 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
661 sprintf (p, "%.0E", fabs (number));
663 /* The C locale always uses a period `.' as a decimal point.
664 Translate to comma if necessary. */
665 if (style->decimal != '.')
667 char *cp = strchr (p, '.');
669 *cp = style->decimal;
672 /* Make exponent have exactly three digits, plus sign. */
674 char *cp = strchr (p, 'E') + 1;
675 long int exponent = strtol (cp, NULL, 10);
676 if (abs (exponent) > 999)
678 sprintf (cp, "%+04ld", exponent);
682 p = strchr (p, '\0');
684 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
686 p = mempcpy (p, ss_data (style->neg_suffix),
687 ss_length (style->neg_suffix));
689 p = mempset (p, ' ', ss_length (style->neg_suffix));
691 assert (p == buf + format->w);
692 memcpy (output, buf, format->w);
697 /* Returns true if the magnitude represented by R should be
698 rounded up when chopped off at DECIMALS decimal places, false
699 if it should be rounded down. */
701 should_round_up (const struct rounder *r, int decimals)
703 int digit = r->string[r->integer_digits + decimals + 1];
704 assert (digit >= '0' && digit <= '9');
708 /* Initializes R for formatting the magnitude of NUMBER to no
709 more than MAX_DECIMAL decimal places. */
711 rounder_init (struct rounder *r, double number, int max_decimals)
713 assert (fabs (number) < 1e41);
714 assert (max_decimals >= 0 && max_decimals <= 16);
715 if (max_decimals == 0)
717 /* Fast path. No rounding needed.
719 We append ".00" to the integer representation because
720 round_up assumes that fractional digits are present. */
721 sprintf (r->string, "%.0f.00", fabs (round (number)));
727 This is more difficult than it really should be because
728 we have to make sure that numbers that are exactly
729 halfway between two representations are always rounded
730 away from zero. This is not what sprintf normally does
731 (usually it rounds to even), so we have to fake it as
732 best we can, by formatting with extra precision and then
733 doing the rounding ourselves.
735 We take up to two rounds to format numbers. In the
736 first round, we obtain 2 digits of precision beyond
737 those requested by the user. If those digits are
738 exactly "50", then in a second round we format with as
739 many digits as are significant in a "double".
741 It might be better to directly implement our own
742 floating-point formatting routine instead of relying on
743 the system's sprintf implementation. But the classic
744 Steele and White paper on printing floating-point
745 numbers does not hint how to do what we want, and it's
746 not obvious how to change their algorithms to do so. It
747 would also be a lot of work. */
748 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
749 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
751 int binary_exponent, decimal_exponent, format_decimals;
752 frexp (number, &binary_exponent);
753 decimal_exponent = binary_exponent * 3 / 10;
754 format_decimals = (DBL_DIG + 1) - decimal_exponent;
755 if (format_decimals > max_decimals + 2)
756 sprintf (r->string, "%.*f", format_decimals, fabs (number));
760 if (r->string[0] == '0')
761 memmove (r->string, &r->string[1], strlen (r->string));
763 r->leading_zeros = strspn (r->string, "0.");
764 r->leading_nines = strspn (r->string, "9.");
765 r->integer_digits = strchr (r->string, '.') - r->string;
766 r->negative = number < 0;
769 /* Returns the number of characters required to format the
770 magnitude represented by R to DECIMALS decimal places.
771 The return value includes integer digits and a decimal point
772 and fractional digits, if any, but it does not include any
773 negative prefix or suffix or other affixes.
775 *INTEGER_DIGITS is set to the number of digits before the
776 decimal point in the output, between 0 and 40.
778 If R represents a negative number and its rounded
779 representation would include at least one nonzero digit,
780 *NEGATIVE is set to true; otherwise, it is set to false. */
782 rounder_width (const struct rounder *r, int decimals,
783 int *integer_digits, bool *negative)
785 /* Calculate base measures. */
786 int width = r->integer_digits;
788 width += decimals + 1;
789 *integer_digits = r->integer_digits;
790 *negative = r->negative;
792 /* Rounding can cause adjustments. */
793 if (should_round_up (r, decimals))
795 /* Rounding up leading 9s adds a new digit (a 1). */
796 if (r->leading_nines >= width)
805 if (r->leading_zeros >= width)
807 /* All digits that remain after rounding are zeros.
808 Therefore we drop the negative sign. */
810 if (r->integer_digits == 0 && decimals == 0)
812 /* No digits at all are left. We need to display
813 at least a single digit (a zero). */
823 /* Formats the magnitude represented by R into OUTPUT, rounding
824 to DECIMALS decimal places. Exactly as many characters as
825 indicated by rounder_width are written. No terminating null
828 rounder_format (const struct rounder *r, int decimals, char *output)
830 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
831 if (should_round_up (r, decimals))
833 if (r->leading_nines < base_width)
835 /* Rounding up. This is the common case where rounding
836 up doesn't add an extra digit. */
838 memcpy (output, r->string, base_width);
839 for (p = output + base_width - 1; ; p--)
841 assert (p >= output);
844 else if (*p >= '0' && *p <= '8')
855 /* Rounding up leading 9s causes the result to be a 1
856 followed by a number of 0s, plus a decimal point. */
859 p = mempset (p, '0', r->integer_digits);
863 p = mempset (p, '0', decimals);
865 assert (p == output + base_width + 1);
871 if (r->integer_digits != 0 || decimals != 0)
873 /* Common case: just copy the digits. */
874 memcpy (output, r->string, base_width);
878 /* No digits remain. The output is just a zero. */
884 /* Helper functions. */
887 static double PURE_FUNCTION
890 static const double p[] =
892 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
893 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
894 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
895 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
898 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
901 /* Returns 256**X. */
902 static double PURE_FUNCTION
905 static const double p[] =
915 18446744073709551616.0
917 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
920 /* Formats non-finite NUMBER into OUTPUT according to the width
923 output_infinite (double number, const struct fmt_spec *format, char *output)
925 assert (!isfinite (number));
931 if (gsl_isnan (number))
933 else if (gsl_isinf (number))
934 s = number > 0 ? "+Infinity" : "-Infinity";
938 buf_copy_str_lpad (output, format->w, s);
941 output_overflow (format, output);
944 /* Formats OUTPUT as a missing value for the given FORMAT. */
946 output_missing (const struct fmt_spec *format, char *output)
948 memset (output, ' ', format->w);
950 if (format->type != FMT_N)
952 int dot_ofs = (format->type == FMT_PCT ? 2
953 : format->type == FMT_E ? 5
955 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
958 output[format->w - 1] = '.';
961 /* Formats OUTPUT for overflow given FORMAT. */
963 output_overflow (const struct fmt_spec *format, char *output)
965 memset (output, '*', format->w);
968 /* Converts the integer part of NUMBER to a packed BCD number
969 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
970 the least significant nibble of the final byte in OUTPUT is
971 set to 0. Returns true if successful, false if NUMBER is not
972 representable. On failure, OUTPUT is cleared to all zero
975 output_bcd_integer (double number, int digits, char *output)
979 assert (digits < sizeof decimal);
982 && number < power10 (digits)
983 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
985 const char *src = decimal;
988 for (i = 0; i < digits / 2; i++)
990 int d0 = *src++ - '0';
991 int d1 = *src++ - '0';
992 *output++ = (d0 << 4) + d1;
995 *output = (*src - '0') << 4;
1001 memset (output, 0, DIV_RND_UP (digits, 2));
1006 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1007 given INTEGER_FORMAT. */
1009 output_binary_integer (uint64_t value, int bytes,
1010 enum integer_format integer_format, char *output)
1012 integer_put (value, integer_format, output, bytes);
1015 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1016 digits in OUTPUT. */
1018 output_hex (const void *data_, size_t bytes, char *output)
1020 const uint8_t *data = data_;
1023 for (i = 0; i < bytes; i++)
1025 static const char hex_digits[] = "0123456789ABCDEF";
1026 *output++ = hex_digits[data[i] >> 4];
1027 *output++ = hex_digits[data[i] & 15];