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/>. */
27 #include <gsl/gsl_math.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/misc.h>
40 #include <libpspp/str.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 /* Format of integers in output (SET WIB). */
66 static enum integer_format output_integer_format = INTEGER_NATIVE;
68 /* Format of reals in output (SET WRB). */
69 static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE;
71 typedef void data_out_converter_func (const union value *,
72 const struct fmt_spec *,
74 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
75 static data_out_converter_func output_##METHOD;
78 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
79 bool require_affixes, char *);
80 static bool output_scientific (double, const struct fmt_spec *,
81 bool require_affixes, char *);
83 static double power10 (int) PURE_FUNCTION;
84 static double power256 (int) PURE_FUNCTION;
86 static void output_infinite (double, const struct fmt_spec *, char *);
87 static void output_missing (const struct fmt_spec *, char *);
88 static void output_overflow (const struct fmt_spec *, char *);
89 static bool output_bcd_integer (double, int digits, char *);
90 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
92 static void output_hex (const void *, size_t bytes, char *);
94 /* Converts the INPUT value into printable form in the exactly
95 FORMAT->W characters in OUTPUT according to format
96 specification FORMAT. No null terminator is appended to the
99 data_out (const union value *input, const struct fmt_spec *format,
102 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
104 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
105 #include "format.def"
108 assert (fmt_check_output (format));
110 converters[format->type] (input, format, output);
113 /* Returns the current output integer format. */
115 data_out_get_integer_format (void)
117 return output_integer_format;
120 /* Sets the output integer format to INTEGER_FORMAT. */
122 data_out_set_integer_format (enum integer_format integer_format)
124 output_integer_format = integer_format;
127 /* Returns the current output float format. */
129 data_out_get_float_format (void)
131 return output_float_format;
134 /* Sets the output float format to FLOAT_FORMAT. */
136 data_out_set_float_format (enum float_format float_format)
138 output_float_format = float_format;
141 /* Main conversion functions. */
143 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
146 output_number (const union value *input, const struct fmt_spec *format,
149 double number = input->f;
151 if (number == SYSMIS)
152 output_missing (format, output);
153 else if (!gsl_finite (number))
154 output_infinite (number, format, output);
157 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
160 rounder_init (&r, number, format->d);
162 if (output_decimal (&r, format, true, output)
163 || output_scientific (number, format, true, output)
164 || output_decimal (&r, format, false, output))
168 if (!output_scientific (number, format, false, output))
169 output_overflow (format, output);
173 /* Outputs N format. */
175 output_N (const union value *input, const struct fmt_spec *format,
178 double number = input->f * power10 (format->d);
179 if (input->f == SYSMIS || number < 0)
180 output_missing (format, output);
184 number = fabs (round (number));
185 if (number < power10 (format->w)
186 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
187 memcpy (output, buf, format->w);
189 output_overflow (format, output);
193 /* Outputs Z format. */
195 output_Z (const union value *input, const struct fmt_spec *format,
198 double number = input->f * power10 (format->d);
200 if (input->f == SYSMIS)
201 output_missing (format, output);
202 else if (fabs (number) >= power10 (format->w)
203 || sprintf (buf, "%0*.0f", format->w,
204 fabs (round (number))) != format->w)
205 output_overflow (format, output);
208 if (number < 0 && strspn (buf, "0") < format->w)
210 char *p = &buf[format->w - 1];
211 *p = "}JKLMNOPQR"[*p - '0'];
213 memcpy (output, buf, format->w);
217 /* Outputs P format. */
219 output_P (const union value *input, const struct fmt_spec *format,
222 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
223 format->w * 2 - 1, output)
225 output[format->w - 1] |= 0xd;
227 output[format->w - 1] |= 0xf;
230 /* Outputs PK format. */
232 output_PK (const union value *input, const struct fmt_spec *format,
235 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
238 /* Outputs IB format. */
240 output_IB (const union value *input, const struct fmt_spec *format,
243 double number = round (input->f * power10 (format->d));
244 if (input->f == SYSMIS
245 || number >= power256 (format->w) / 2 - 1
246 || number < -power256 (format->w) / 2)
247 memset (output, 0, format->w);
250 uint64_t integer = fabs (number);
253 output_binary_integer (integer, format->w, output_integer_format,
258 /* Outputs PIB format. */
260 output_PIB (const union value *input, const struct fmt_spec *format,
263 double number = round (input->f * power10 (format->d));
264 if (input->f == SYSMIS
265 || number < 0 || number >= power256 (format->w))
266 memset (output, 0, format->w);
268 output_binary_integer (number, format->w, output_integer_format, output);
271 /* Outputs PIBHEX format. */
273 output_PIBHEX (const union value *input, const struct fmt_spec *format,
276 double number = round (input->f);
277 if (input->f == SYSMIS)
278 output_missing (format, output);
279 else if (input->f < 0 || number >= power256 (format->w / 2))
280 output_overflow (format, output);
284 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
285 output_hex (tmp, format->w / 2, output);
289 /* Outputs RB format. */
291 output_RB (const union value *input, const struct fmt_spec *format,
295 memcpy (output, &d, format->w);
298 /* Outputs RBHEX format. */
300 output_RBHEX (const union value *input, const struct fmt_spec *format,
304 output_hex (&d, format->w / 2, output);
307 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
308 DATETIME, TIME, and DTIME formats. */
310 output_date (const union value *input, const struct fmt_spec *format,
313 double number = input->f;
314 int year, month, day, yday;
316 const char *template = fmt_date_template (format->type);
317 size_t template_width = strlen (template);
318 int excess_width = format->w - template_width;
323 assert (format->w >= template_width);
324 if (number == SYSMIS)
327 if (fmt_get_category (format->type) == FMT_CAT_DATE)
331 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
332 &year, &month, &day, &yday);
333 number = fmod (number, 60. * 60. * 24.);
336 year = month = day = yday = 0;
338 while (*template != '\0')
342 while (template[count] == ch)
350 p += sprintf (p, "%02d", day);
352 p += sprintf (p, "%03d", yday);
356 p += sprintf (p, "%02d", month);
359 static const char *months[12] =
361 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
362 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
364 p = stpcpy (p, months[month - 1]);
368 if (count >= 4 || excess_width >= 2)
371 p += sprintf (p, "%04d", year);
372 else if (format->type == FMT_DATETIME)
373 p = stpcpy (p, "****");
379 int offset = year - get_epoch ();
380 if (offset < 0 || offset > 99)
382 p += sprintf (p, "%02d", abs (year) % 100);
386 p += sprintf (p, "%d", (month - 1) / 3 + 1);
389 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
394 number = fabs (number);
395 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
396 number = fmod (number, 60. * 60. * 24.);
401 number = fabs (number);
402 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
403 number = fmod (number, 60. * 60.);
406 p += sprintf (p, "%02d", (int) floor (number / 60.));
407 number = fmod (number, 60.);
408 excess_width = format->w - (p - tmp);
409 if (excess_width < 0)
411 if (excess_width == 3 || excess_width == 4
412 || (excess_width >= 5 && format->d == 0))
413 p += sprintf (p, ":%02d", (int) number);
414 else if (excess_width >= 5)
416 int d = MIN (format->d, excess_width - 4);
418 sprintf (p, ":%0*.*f", w, d, number);
419 if (fmt_decimal_char (FMT_F) != '.')
421 char *cp = strchr (p, '.');
423 *cp = fmt_decimal_char (FMT_F);
438 buf_copy_lpad (output, format->w, tmp, p - tmp);
442 output_overflow (format, output);
446 output_missing (format, output);
450 /* Outputs WKDAY format. */
452 output_WKDAY (const union value *input, const struct fmt_spec *format,
455 static const char *weekdays[7] =
457 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
458 "THURSDAY", "FRIDAY", "SATURDAY",
461 if (input->f >= 1 && input->f < 8)
462 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
465 if (input->f != SYSMIS)
466 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
467 output_missing (format, output);
471 /* Outputs MONTH format. */
473 output_MONTH (const union value *input, const struct fmt_spec *format,
476 static const char *months[12] =
478 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
479 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
482 if (input->f >= 1 && input->f < 13)
483 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
486 if (input->f != SYSMIS)
487 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
488 output_missing (format, output);
492 /* Outputs A format. */
494 output_A (const union value *input, const struct fmt_spec *format,
497 memcpy (output, input->s, format->w);
500 /* Outputs AHEX format. */
502 output_AHEX (const union value *input, const struct fmt_spec *format,
505 output_hex (input->s, format->w, output);
508 /* Decimal and scientific formatting. */
510 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
511 increments *WIDTH by REQUEST and return true.
512 Otherwise returns false without changing *WIDTH. */
514 allocate_space (int request, int max_width, int *width)
516 assert (*width <= max_width);
517 if (request + *width <= max_width)
526 /* Tries to compose the number represented by R, in the style of
527 FORMAT, into OUTPUT. Returns true if successful, false on
528 failure, which occurs if FORMAT's width is too narrow. If
529 REQUIRE_AFFIXES is true, then the prefix and suffix specified
530 by FORMAT's style must be included; otherwise, they may be
531 omitted to make the number fit. */
533 output_decimal (const struct rounder *r, const struct fmt_spec *format,
534 bool require_affixes, char *output)
536 const struct fmt_number_style *style = fmt_get_style (format->type);
539 for (decimals = format->d; decimals >= 0; decimals--)
541 /* Formatted version of magnitude of NUMBER. */
544 /* Number of digits in MAGNITUDE's integer and fractional parts. */
547 /* Amount of space within the field width already claimed.
548 Initially this is the width of MAGNITUDE, then it is reduced
549 in stages as space is allocated to prefixes and suffixes and
550 grouping characters. */
553 /* Include various decorations? */
558 /* Position in output. */
561 /* Make sure there's room for the number's magnitude, plus
562 the negative suffix, plus (if negative) the negative
564 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
565 width += ss_length (style->neg_suffix);
567 width += ss_length (style->neg_prefix);
568 if (width > format->w)
571 /* If there's room for the prefix and suffix, allocate
572 space. If the affixes are required, but there's no
574 add_affixes = allocate_space (fmt_affix_width (style),
576 if (!add_affixes && require_affixes)
579 /* Check whether we should include grouping characters.
580 We need room for a complete set or we don't insert any at all.
581 We don't include grouping characters if decimal places were
582 requested but they were all dropped. */
583 add_grouping = (style->grouping != 0
584 && integer_digits > 3
585 && (format->d == 0 || decimals > 0)
586 && allocate_space ((integer_digits - 1) / 3,
589 /* Format the number's magnitude. */
590 rounder_format (r, decimals, magnitude);
592 /* Assemble number. */
594 if (format->w > width)
595 p = mempset (p, ' ', format->w - width);
597 p = mempcpy (p, ss_data (style->neg_prefix),
598 ss_length (style->neg_prefix));
600 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
602 p = mempcpy (p, magnitude, integer_digits);
606 for (i = 0; i < integer_digits; i++)
608 if (i > 0 && (integer_digits - i) % 3 == 0)
609 *p++ = style->grouping;
615 *p++ = style->decimal;
616 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
619 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
621 p = mempcpy (p, ss_data (style->neg_suffix),
622 ss_length (style->neg_suffix));
624 p = mempset (p, ' ', ss_length (style->neg_suffix));
625 assert (p == output + format->w);
632 /* Formats NUMBER into OUTPUT in scientific notation according to
633 the style of the format specified in FORMAT. */
635 output_scientific (double number, const struct fmt_spec *format,
636 bool require_affixes, char *output)
638 const struct fmt_number_style *style = fmt_get_style (format->type);
644 /* Allocate minimum required space. */
645 width = 6 + ss_length (style->neg_suffix);
647 width += ss_length (style->neg_prefix);
648 if (width > format->w)
651 /* Check for room for prefix and suffix. */
652 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
653 if (require_affixes && !add_affixes)
656 /* Figure out number of characters we can use for the fraction,
657 if any. (If that turns out to be 1, then we'll output a
658 decimal point without any digits following; that's what the
659 # flag does in the call to sprintf, below.) */
660 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
661 if (format->type != FMT_E && fraction_width == 1)
663 width += fraction_width;
665 /* Format (except suffix). */
667 if (width < format->w)
668 p = mempset (p, ' ', format->w - width);
670 p = mempcpy (p, ss_data (style->neg_prefix),
671 ss_length (style->neg_prefix));
673 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
674 if (fraction_width > 0)
675 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
677 sprintf (p, "%.0E", fabs (number));
679 /* The C locale always uses a period `.' as a decimal point.
680 Translate to comma if necessary. */
681 if (style->decimal != '.')
683 char *cp = strchr (p, '.');
685 *cp = style->decimal;
688 /* Make exponent have exactly three digits, plus sign. */
690 char *cp = strchr (p, 'E') + 1;
691 long int exponent = strtol (cp, NULL, 10);
692 if (abs (exponent) > 999)
694 sprintf (cp, "%+04ld", exponent);
698 p = strchr (p, '\0');
700 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
702 p = mempcpy (p, ss_data (style->neg_suffix),
703 ss_length (style->neg_suffix));
705 p = mempset (p, ' ', ss_length (style->neg_suffix));
707 assert (p == buf + format->w);
708 memcpy (output, buf, format->w);
714 /* Return X rounded to the nearest integer,
715 rounding ties away from zero. */
719 return x >= 0.0 ? floor (x + .5) : ceil (x - .5);
721 #endif /* !HAVE_ROUND */
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 (!gsl_finite (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];