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/magic.h>
38 #include <libpspp/message.h>
39 #include <libpspp/misc.h>
40 #include <libpspp/misc.h>
41 #include <libpspp/str.h>
46 #define _(msgid) gettext (msgid)
48 /* A representation of a number that can be quickly rounded to
49 any desired number of decimal places (up to a specified
53 char string[64]; /* Magnitude of number with excess precision. */
54 int integer_digits; /* Number of digits before decimal point. */
55 int leading_nines; /* Number of `9's or `.'s at start of string. */
56 int leading_zeros; /* Number of `0's or `.'s at start of string. */
57 bool negative; /* Is the number negative? */
60 static void rounder_init (struct rounder *, double number, int max_decimals);
61 static int rounder_width (const struct rounder *, int decimals,
62 int *integer_digits, bool *negative);
63 static void rounder_format (const struct rounder *, int decimals,
66 /* Format of integers in output (SET WIB). */
67 static enum integer_format output_integer_format = INTEGER_NATIVE;
69 /* Format of reals in output (SET WRB). */
70 static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE;
72 typedef void data_out_converter_func (const union value *,
73 const struct fmt_spec *,
75 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
76 static data_out_converter_func output_##METHOD;
79 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
80 bool require_affixes, char *);
81 static bool output_scientific (double, const struct fmt_spec *,
82 bool require_affixes, char *);
84 static double power10 (int) PURE_FUNCTION;
85 static double power256 (int) PURE_FUNCTION;
87 static void output_infinite (double, const struct fmt_spec *, char *);
88 static void output_missing (const struct fmt_spec *, char *);
89 static void output_overflow (const struct fmt_spec *, char *);
90 static bool output_bcd_integer (double, int digits, char *);
91 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
93 static void output_hex (const void *, size_t bytes, char *);
95 /* Converts the INPUT value into printable form in the exactly
96 FORMAT->W characters in OUTPUT according to format
97 specification FORMAT. No null terminator is appended to the
100 data_out (const union value *input, const struct fmt_spec *format,
103 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
105 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
106 #include "format.def"
109 assert (fmt_check_output (format));
111 converters[format->type] (input, format, output);
114 /* Returns the current output integer format. */
116 data_out_get_integer_format (void)
118 return output_integer_format;
121 /* Sets the output integer format to INTEGER_FORMAT. */
123 data_out_set_integer_format (enum integer_format integer_format)
125 output_integer_format = integer_format;
128 /* Returns the current output float format. */
130 data_out_get_float_format (void)
132 return output_float_format;
135 /* Sets the output float format to FLOAT_FORMAT. */
137 data_out_set_float_format (enum float_format float_format)
139 output_float_format = float_format;
142 /* Main conversion functions. */
144 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
147 output_number (const union value *input, const struct fmt_spec *format,
150 double number = input->f;
152 if (number == SYSMIS)
153 output_missing (format, output);
154 else if (!gsl_finite (number))
155 output_infinite (number, format, output);
158 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
161 rounder_init (&r, number, format->d);
163 if (output_decimal (&r, format, true, output)
164 || output_scientific (number, format, true, output)
165 || output_decimal (&r, format, false, output))
169 if (!output_scientific (number, format, false, output))
170 output_overflow (format, output);
174 /* Outputs N format. */
176 output_N (const union value *input, const struct fmt_spec *format,
179 double number = input->f * power10 (format->d);
180 if (input->f == SYSMIS || number < 0)
181 output_missing (format, output);
185 number = fabs (round (number));
186 if (number < power10 (format->w)
187 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
188 memcpy (output, buf, format->w);
190 output_overflow (format, output);
194 /* Outputs Z format. */
196 output_Z (const union value *input, const struct fmt_spec *format,
199 double number = input->f * power10 (format->d);
201 if (input->f == SYSMIS)
202 output_missing (format, output);
203 else if (fabs (number) >= power10 (format->w)
204 || sprintf (buf, "%0*.0f", format->w,
205 fabs (round (number))) != format->w)
206 output_overflow (format, output);
209 if (number < 0 && strspn (buf, "0") < format->w)
211 char *p = &buf[format->w - 1];
212 *p = "}JKLMNOPQR"[*p - '0'];
214 memcpy (output, buf, format->w);
218 /* Outputs P format. */
220 output_P (const union value *input, const struct fmt_spec *format,
223 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
224 format->w * 2 - 1, output)
226 output[format->w - 1] |= 0xd;
228 output[format->w - 1] |= 0xf;
231 /* Outputs PK format. */
233 output_PK (const union value *input, const struct fmt_spec *format,
236 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
239 /* Outputs IB format. */
241 output_IB (const union value *input, const struct fmt_spec *format,
244 double number = round (input->f * power10 (format->d));
245 if (input->f == SYSMIS
246 || number >= power256 (format->w) / 2 - 1
247 || number < -power256 (format->w) / 2)
248 memset (output, 0, format->w);
251 uint64_t integer = fabs (number);
254 output_binary_integer (integer, format->w, output_integer_format,
259 /* Outputs PIB format. */
261 output_PIB (const union value *input, const struct fmt_spec *format,
264 double number = round (input->f * power10 (format->d));
265 if (input->f == SYSMIS
266 || number < 0 || number >= power256 (format->w))
267 memset (output, 0, format->w);
269 output_binary_integer (number, format->w, output_integer_format, output);
272 /* Outputs PIBHEX format. */
274 output_PIBHEX (const union value *input, const struct fmt_spec *format,
277 double number = round (input->f);
278 if (input->f == SYSMIS)
279 output_missing (format, output);
280 else if (input->f < 0 || number >= power256 (format->w / 2))
281 output_overflow (format, output);
285 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
286 output_hex (tmp, format->w / 2, output);
290 /* Outputs RB format. */
292 output_RB (const union value *input, const struct fmt_spec *format,
296 memcpy (output, &d, format->w);
299 /* Outputs RBHEX format. */
301 output_RBHEX (const union value *input, const struct fmt_spec *format,
305 output_hex (&d, format->w / 2, output);
308 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
309 DATETIME, TIME, and DTIME formats. */
311 output_date (const union value *input, const struct fmt_spec *format,
314 double number = input->f;
315 int year, month, day, yday;
317 const char *template = fmt_date_template (format->type);
318 size_t template_width = strlen (template);
319 int excess_width = format->w - template_width;
324 assert (format->w >= template_width);
325 if (number == SYSMIS)
328 if (fmt_get_category (format->type) == FMT_CAT_DATE)
332 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
333 &year, &month, &day, &yday);
334 number = fmod (number, 60. * 60. * 24.);
337 year = month = day = yday = 0;
339 while (*template != '\0')
343 while (template[count] == ch)
351 p += sprintf (p, "%02d", day);
353 p += sprintf (p, "%03d", yday);
357 p += sprintf (p, "%02d", month);
360 static const char *months[12] =
362 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
363 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
365 p = stpcpy (p, months[month - 1]);
369 if (count >= 4 || excess_width >= 2)
372 p += sprintf (p, "%04d", year);
373 else if (format->type == FMT_DATETIME)
374 p = stpcpy (p, "****");
380 int offset = year - get_epoch ();
381 if (offset < 0 || offset > 99)
383 p += sprintf (p, "%02d", abs (year) % 100);
387 p += sprintf (p, "%d", (month - 1) / 3 + 1);
390 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
395 number = fabs (number);
396 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
397 number = fmod (number, 60. * 60. * 24.);
402 number = fabs (number);
403 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
404 number = fmod (number, 60. * 60.);
407 p += sprintf (p, "%02d", (int) floor (number / 60.));
408 number = fmod (number, 60.);
409 excess_width = format->w - (p - tmp);
410 if (excess_width < 0)
412 if (excess_width == 3 || excess_width == 4
413 || (excess_width >= 5 && format->d == 0))
414 p += sprintf (p, ":%02d", (int) number);
415 else if (excess_width >= 5)
417 int d = MIN (format->d, excess_width - 4);
419 sprintf (p, ":%0*.*f", w, d, number);
420 if (fmt_decimal_char (FMT_F) != '.')
422 char *cp = strchr (p, '.');
424 *cp = fmt_decimal_char (FMT_F);
439 buf_copy_lpad (output, format->w, tmp, p - tmp);
443 output_overflow (format, output);
447 output_missing (format, output);
451 /* Outputs WKDAY format. */
453 output_WKDAY (const union value *input, const struct fmt_spec *format,
456 static const char *weekdays[7] =
458 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
459 "THURSDAY", "FRIDAY", "SATURDAY",
462 if (input->f >= 1 && input->f < 8)
463 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
466 if (input->f != SYSMIS)
467 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
468 output_missing (format, output);
472 /* Outputs MONTH format. */
474 output_MONTH (const union value *input, const struct fmt_spec *format,
477 static const char *months[12] =
479 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
480 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
483 if (input->f >= 1 && input->f < 13)
484 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
487 if (input->f != SYSMIS)
488 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
489 output_missing (format, output);
493 /* Outputs A format. */
495 output_A (const union value *input, const struct fmt_spec *format,
498 memcpy (output, input->s, format->w);
501 /* Outputs AHEX format. */
503 output_AHEX (const union value *input, const struct fmt_spec *format,
506 output_hex (input->s, format->w, output);
509 /* Decimal and scientific formatting. */
511 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
512 increments *WIDTH by REQUEST and return true.
513 Otherwise returns false without changing *WIDTH. */
515 allocate_space (int request, int max_width, int *width)
517 assert (*width <= max_width);
518 if (request + *width <= max_width)
527 /* Tries to compose the number represented by R, in the style of
528 FORMAT, into OUTPUT. Returns true if successful, false on
529 failure, which occurs if FORMAT's width is too narrow. If
530 REQUIRE_AFFIXES is true, then the prefix and suffix specified
531 by FORMAT's style must be included; otherwise, they may be
532 omitted to make the number fit. */
534 output_decimal (const struct rounder *r, const struct fmt_spec *format,
535 bool require_affixes, char *output)
537 const struct fmt_number_style *style = fmt_get_style (format->type);
540 for (decimals = format->d; decimals >= 0; decimals--)
542 /* Formatted version of magnitude of NUMBER. */
545 /* Number of digits in MAGNITUDE's integer and fractional parts. */
548 /* Amount of space within the field width already claimed.
549 Initially this is the width of MAGNITUDE, then it is reduced
550 in stages as space is allocated to prefixes and suffixes and
551 grouping characters. */
554 /* Include various decorations? */
559 /* Position in output. */
562 /* Make sure there's room for the number's magnitude, plus
563 the negative suffix, plus (if negative) the negative
565 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
566 width += ss_length (style->neg_suffix);
568 width += ss_length (style->neg_prefix);
569 if (width > format->w)
572 /* If there's room for the prefix and suffix, allocate
573 space. If the affixes are required, but there's no
575 add_affixes = allocate_space (fmt_affix_width (style),
577 if (!add_affixes && require_affixes)
580 /* Check whether we should include grouping characters.
581 We need room for a complete set or we don't insert any at all.
582 We don't include grouping characters if decimal places were
583 requested but they were all dropped. */
584 add_grouping = (style->grouping != 0
585 && integer_digits > 3
586 && (format->d == 0 || decimals > 0)
587 && allocate_space ((integer_digits - 1) / 3,
590 /* Format the number's magnitude. */
591 rounder_format (r, decimals, magnitude);
593 /* Assemble number. */
595 if (format->w > width)
596 p = mempset (p, ' ', format->w - width);
598 p = mempcpy (p, ss_data (style->neg_prefix),
599 ss_length (style->neg_prefix));
601 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
603 p = mempcpy (p, magnitude, integer_digits);
607 for (i = 0; i < integer_digits; i++)
609 if (i > 0 && (integer_digits - i) % 3 == 0)
610 *p++ = style->grouping;
616 *p++ = style->decimal;
617 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
620 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
622 p = mempcpy (p, ss_data (style->neg_suffix),
623 ss_length (style->neg_suffix));
625 p = mempset (p, ' ', ss_length (style->neg_suffix));
626 assert (p == output + format->w);
633 /* Formats NUMBER into OUTPUT in scientific notation according to
634 the style of the format specified in FORMAT. */
636 output_scientific (double number, const struct fmt_spec *format,
637 bool require_affixes, char *output)
639 const struct fmt_number_style *style = fmt_get_style (format->type);
645 /* Allocate minimum required space. */
646 width = 6 + ss_length (style->neg_suffix);
648 width += ss_length (style->neg_prefix);
649 if (width > format->w)
652 /* Check for room for prefix and suffix. */
653 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
654 if (require_affixes && !add_affixes)
657 /* Figure out number of characters we can use for the fraction,
658 if any. (If that turns out to be 1, then we'll output a
659 decimal point without any digits following; that's what the
660 # flag does in the call to sprintf, below.) */
661 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
662 if (format->type != FMT_E && fraction_width == 1)
664 width += fraction_width;
666 /* Format (except suffix). */
668 if (width < format->w)
669 p = mempset (p, ' ', format->w - width);
671 p = mempcpy (p, ss_data (style->neg_prefix),
672 ss_length (style->neg_prefix));
674 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
675 if (fraction_width > 0)
676 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
678 sprintf (p, "%.0E", fabs (number));
680 /* The C locale always uses a period `.' as a decimal point.
681 Translate to comma if necessary. */
682 if (style->decimal != '.')
684 char *cp = strchr (p, '.');
686 *cp = style->decimal;
689 /* Make exponent have exactly three digits, plus sign. */
691 char *cp = strchr (p, 'E') + 1;
692 long int exponent = strtol (cp, NULL, 10);
693 if (abs (exponent) > 999)
695 sprintf (cp, "%+04ld", exponent);
699 p = strchr (p, '\0');
701 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
703 p = mempcpy (p, ss_data (style->neg_suffix),
704 ss_length (style->neg_suffix));
706 p = mempset (p, ' ', ss_length (style->neg_suffix));
708 assert (p == buf + format->w);
709 memcpy (output, buf, format->w);
715 /* Return X rounded to the nearest integer,
716 rounding ties away from zero. */
720 return x >= 0.0 ? floor (x + .5) : ceil (x - .5);
722 #endif /* !HAVE_ROUND */
724 /* Returns true if the magnitude represented by R should be
725 rounded up when chopped off at DECIMALS decimal places, false
726 if it should be rounded down. */
728 should_round_up (const struct rounder *r, int decimals)
730 int digit = r->string[r->integer_digits + decimals + 1];
731 assert (digit >= '0' && digit <= '9');
735 /* Initializes R for formatting the magnitude of NUMBER to no
736 more than MAX_DECIMAL decimal places. */
738 rounder_init (struct rounder *r, double number, int max_decimals)
740 assert (fabs (number) < 1e41);
741 assert (max_decimals >= 0 && max_decimals <= 16);
742 if (max_decimals == 0)
744 /* Fast path. No rounding needed.
746 We append ".00" to the integer representation because
747 round_up assumes that fractional digits are present. */
748 sprintf (r->string, "%.0f.00", fabs (round (number)));
754 This is more difficult than it really should be because
755 we have to make sure that numbers that are exactly
756 halfway between two representations are always rounded
757 away from zero. This is not what sprintf normally does
758 (usually it rounds to even), so we have to fake it as
759 best we can, by formatting with extra precision and then
760 doing the rounding ourselves.
762 We take up to two rounds to format numbers. In the
763 first round, we obtain 2 digits of precision beyond
764 those requested by the user. If those digits are
765 exactly "50", then in a second round we format with as
766 many digits as are significant in a "double".
768 It might be better to directly implement our own
769 floating-point formatting routine instead of relying on
770 the system's sprintf implementation. But the classic
771 Steele and White paper on printing floating-point
772 numbers does not hint how to do what we want, and it's
773 not obvious how to change their algorithms to do so. It
774 would also be a lot of work. */
775 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
776 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
778 int binary_exponent, decimal_exponent, format_decimals;
779 frexp (number, &binary_exponent);
780 decimal_exponent = binary_exponent * 3 / 10;
781 format_decimals = (DBL_DIG + 1) - decimal_exponent;
782 if (format_decimals > max_decimals + 2)
783 sprintf (r->string, "%.*f", format_decimals, fabs (number));
787 if (r->string[0] == '0')
788 memmove (r->string, &r->string[1], strlen (r->string));
790 r->leading_zeros = strspn (r->string, "0.");
791 r->leading_nines = strspn (r->string, "9.");
792 r->integer_digits = strchr (r->string, '.') - r->string;
793 r->negative = number < 0;
796 /* Returns the number of characters required to format the
797 magnitude represented by R to DECIMALS decimal places.
798 The return value includes integer digits and a decimal point
799 and fractional digits, if any, but it does not include any
800 negative prefix or suffix or other affixes.
802 *INTEGER_DIGITS is set to the number of digits before the
803 decimal point in the output, between 0 and 40.
805 If R represents a negative number and its rounded
806 representation would include at least one nonzero digit,
807 *NEGATIVE is set to true; otherwise, it is set to false. */
809 rounder_width (const struct rounder *r, int decimals,
810 int *integer_digits, bool *negative)
812 /* Calculate base measures. */
813 int width = r->integer_digits;
815 width += decimals + 1;
816 *integer_digits = r->integer_digits;
817 *negative = r->negative;
819 /* Rounding can cause adjustments. */
820 if (should_round_up (r, decimals))
822 /* Rounding up leading 9s adds a new digit (a 1). */
823 if (r->leading_nines >= width)
832 if (r->leading_zeros >= width)
834 /* All digits that remain after rounding are zeros.
835 Therefore we drop the negative sign. */
837 if (r->integer_digits == 0 && decimals == 0)
839 /* No digits at all are left. We need to display
840 at least a single digit (a zero). */
850 /* Formats the magnitude represented by R into OUTPUT, rounding
851 to DECIMALS decimal places. Exactly as many characters as
852 indicated by rounder_width are written. No terminating null
855 rounder_format (const struct rounder *r, int decimals, char *output)
857 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
858 if (should_round_up (r, decimals))
860 if (r->leading_nines < base_width)
862 /* Rounding up. This is the common case where rounding
863 up doesn't add an extra digit. */
865 memcpy (output, r->string, base_width);
866 for (p = output + base_width - 1; ; p--)
868 assert (p >= output);
871 else if (*p >= '0' && *p <= '8')
882 /* Rounding up leading 9s causes the result to be a 1
883 followed by a number of 0s, plus a decimal point. */
886 p = mempset (p, '0', r->integer_digits);
890 p = mempset (p, '0', decimals);
892 assert (p == output + base_width + 1);
898 if (r->integer_digits != 0 || decimals != 0)
900 /* Common case: just copy the digits. */
901 memcpy (output, r->string, base_width);
905 /* No digits remain. The output is just a zero. */
911 /* Helper functions. */
914 static double PURE_FUNCTION
917 static const double p[] =
919 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
920 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
921 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
922 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
925 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
928 /* Returns 256**X. */
929 static double PURE_FUNCTION
932 static const double p[] =
942 18446744073709551616.0
944 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
947 /* Formats non-finite NUMBER into OUTPUT according to the width
950 output_infinite (double number, const struct fmt_spec *format, char *output)
952 assert (!gsl_finite (number));
960 else if (isinf (number))
961 s = number > 0 ? "+Infinity" : "-Infinity";
965 buf_copy_str_lpad (output, format->w, s);
968 output_overflow (format, output);
971 /* Formats OUTPUT as a missing value for the given FORMAT. */
973 output_missing (const struct fmt_spec *format, char *output)
975 memset (output, ' ', format->w);
977 if (format->type != FMT_N)
979 int dot_ofs = (format->type == FMT_PCT ? 2
980 : format->type == FMT_E ? 5
982 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
985 output[format->w - 1] = '.';
988 /* Formats OUTPUT for overflow given FORMAT. */
990 output_overflow (const struct fmt_spec *format, char *output)
992 memset (output, '*', format->w);
995 /* Converts the integer part of NUMBER to a packed BCD number
996 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
997 the least significant nibble of the final byte in OUTPUT is
998 set to 0. Returns true if successful, false if NUMBER is not
999 representable. On failure, OUTPUT is cleared to all zero
1002 output_bcd_integer (double number, int digits, char *output)
1006 assert (digits < sizeof decimal);
1007 if (number != SYSMIS
1009 && number < power10 (digits)
1010 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1012 const char *src = decimal;
1015 for (i = 0; i < digits / 2; i++)
1017 int d0 = *src++ - '0';
1018 int d1 = *src++ - '0';
1019 *output++ = (d0 << 4) + d1;
1022 *output = (*src - '0') << 4;
1028 memset (output, 0, DIV_RND_UP (digits, 2));
1033 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1034 given INTEGER_FORMAT. */
1036 output_binary_integer (uint64_t value, int bytes,
1037 enum integer_format integer_format, char *output)
1039 integer_put (value, integer_format, output, bytes);
1042 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1043 digits in OUTPUT. */
1045 output_hex (const void *data_, size_t bytes, char *output)
1047 const uint8_t *data = data_;
1050 for (i = 0; i < bytes; i++)
1052 static const char hex_digits[] = "0123456789ABCDEF";
1053 *output++ = hex_digits[data[i] >> 4];
1054 *output++ = hex_digits[data[i] & 15];