1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 #include <gsl/gsl_math.h>
36 #include <libpspp/assertion.h>
37 #include <libpspp/float-format.h>
38 #include <libpspp/integer-format.h>
39 #include <libpspp/magic.h>
40 #include <libpspp/message.h>
41 #include <libpspp/misc.h>
42 #include <libpspp/misc.h>
43 #include <libpspp/str.h>
48 #define _(msgid) gettext (msgid)
50 /* A representation of a number that can be quickly rounded to
51 any desired number of decimal places (up to a specified
55 char string[64]; /* Magnitude of number with excess precision. */
56 int integer_digits; /* Number of digits before decimal point. */
57 int leading_nines; /* Number of `9's or `.'s at start of string. */
58 int leading_zeros; /* Number of `0's or `.'s at start of string. */
59 bool negative; /* Is the number negative? */
62 static void rounder_init (struct rounder *, double number, int max_decimals);
63 static int rounder_width (const struct rounder *, int decimals,
64 int *integer_digits, bool *negative);
65 static void rounder_format (const struct rounder *, int decimals,
68 /* Format of integers in output (SET WIB). */
69 static enum integer_format output_integer_format = INTEGER_NATIVE;
71 /* Format of reals in output (SET WRB). */
72 static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE;
74 typedef void data_out_converter_func (const union value *,
75 const struct fmt_spec *,
77 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
78 static data_out_converter_func output_##METHOD;
81 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
82 bool require_affixes, char *);
83 static bool output_scientific (double, const struct fmt_spec *,
84 bool require_affixes, char *);
86 static double power10 (int) PURE_FUNCTION;
87 static double power256 (int) PURE_FUNCTION;
89 static void output_infinite (double, const struct fmt_spec *, char *);
90 static void output_missing (const struct fmt_spec *, char *);
91 static void output_overflow (const struct fmt_spec *, char *);
92 static bool output_bcd_integer (double, int digits, char *);
93 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
95 static void output_hex (const void *, size_t bytes, char *);
97 /* Converts the INPUT value into printable form in the exactly
98 FORMAT->W characters in OUTPUT according to format
99 specification FORMAT. No null terminator is appended to the
102 data_out (const union value *input, const struct fmt_spec *format,
105 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
107 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
108 #include "format.def"
111 assert (fmt_check_output (format));
113 converters[format->type] (input, format, output);
116 /* Returns the current output integer format. */
118 data_out_get_integer_format (void)
120 return output_integer_format;
123 /* Sets the output integer format to INTEGER_FORMAT. */
125 data_out_set_integer_format (enum integer_format integer_format)
127 output_integer_format = integer_format;
130 /* Returns the current output float format. */
132 data_out_get_float_format (void)
134 return output_float_format;
137 /* Sets the output float format to FLOAT_FORMAT. */
139 data_out_set_float_format (enum float_format float_format)
141 output_float_format = float_format;
144 /* Main conversion functions. */
146 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
149 output_number (const union value *input, const struct fmt_spec *format,
152 double number = input->f;
154 if (number == SYSMIS)
155 output_missing (format, output);
156 else if (!gsl_finite (number))
157 output_infinite (number, format, output);
160 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
163 rounder_init (&r, number, format->d);
165 if (output_decimal (&r, format, true, output)
166 || output_scientific (number, format, true, output)
167 || output_decimal (&r, format, false, output))
171 if (!output_scientific (number, format, false, output))
172 output_overflow (format, output);
176 /* Outputs N format. */
178 output_N (const union value *input, const struct fmt_spec *format,
181 double number = input->f * power10 (format->d);
182 if (input->f == SYSMIS || number < 0)
183 output_missing (format, output);
187 number = fabs (round (number));
188 if (number < power10 (format->w)
189 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
190 memcpy (output, buf, format->w);
192 output_overflow (format, output);
196 /* Outputs Z format. */
198 output_Z (const union value *input, const struct fmt_spec *format,
201 double number = input->f * power10 (format->d);
203 if (input->f == SYSMIS)
204 output_missing (format, output);
205 else if (fabs (number) >= power10 (format->w)
206 || sprintf (buf, "%0*.0f", format->w,
207 fabs (round (number))) != format->w)
208 output_overflow (format, output);
211 if (number < 0 && strspn (buf, "0") < format->w)
213 char *p = &buf[format->w - 1];
214 *p = "}JKLMNOPQR"[*p - '0'];
216 memcpy (output, buf, format->w);
220 /* Outputs P format. */
222 output_P (const union value *input, const struct fmt_spec *format,
225 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
226 format->w * 2 - 1, output)
228 output[format->w - 1] |= 0xd;
230 output[format->w - 1] |= 0xf;
233 /* Outputs PK format. */
235 output_PK (const union value *input, const struct fmt_spec *format,
238 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
241 /* Outputs IB format. */
243 output_IB (const union value *input, const struct fmt_spec *format,
246 double number = round (input->f * power10 (format->d));
247 if (input->f == SYSMIS
248 || number >= power256 (format->w) / 2 - 1
249 || number < -power256 (format->w) / 2)
250 memset (output, 0, format->w);
253 uint64_t integer = fabs (number);
256 output_binary_integer (integer, format->w, output_integer_format,
261 /* Outputs PIB format. */
263 output_PIB (const union value *input, const struct fmt_spec *format,
266 double number = round (input->f * power10 (format->d));
267 if (input->f == SYSMIS
268 || number < 0 || number >= power256 (format->w))
269 memset (output, 0, format->w);
271 output_binary_integer (number, format->w, output_integer_format, output);
274 /* Outputs PIBHEX format. */
276 output_PIBHEX (const union value *input, const struct fmt_spec *format,
279 double number = round (input->f);
280 if (input->f == SYSMIS)
281 output_missing (format, output);
282 else if (input->f < 0 || number >= power256 (format->w / 2))
283 output_overflow (format, output);
287 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
288 output_hex (tmp, format->w / 2, output);
292 /* Outputs RB format. */
294 output_RB (const union value *input, const struct fmt_spec *format,
298 memcpy (output, &d, format->w);
301 /* Outputs RBHEX format. */
303 output_RBHEX (const union value *input, const struct fmt_spec *format,
307 output_hex (&d, format->w / 2, output);
310 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
311 DATETIME, TIME, and DTIME formats. */
313 output_date (const union value *input, const struct fmt_spec *format,
316 double number = input->f;
317 int year, month, day, yday;
319 const char *template = fmt_date_template (format->type);
320 size_t template_width = strlen (template);
321 int excess_width = format->w - template_width;
326 assert (format->w >= template_width);
327 if (number == SYSMIS)
330 if (fmt_get_category (format->type) == FMT_CAT_DATE)
334 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
335 &year, &month, &day, &yday);
336 number = fmod (number, 60. * 60. * 24.);
339 year = month = day = yday = 0;
341 while (*template != '\0')
345 while (template[count] == ch)
353 p += sprintf (p, "%02d", day);
355 p += sprintf (p, "%03d", yday);
359 p += sprintf (p, "%02d", month);
362 static const char *months[12] =
364 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
365 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
367 p = stpcpy (p, months[month - 1]);
371 if (count >= 4 || excess_width >= 2)
374 p += sprintf (p, "%04d", year);
375 else if (format->type == FMT_DATETIME)
376 p = stpcpy (p, "****");
382 int offset = year - get_epoch ();
383 if (offset < 0 || offset > 99)
385 p += sprintf (p, "%02d", abs (year) % 100);
389 p += sprintf (p, "%d", (month - 1) / 3 + 1);
392 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
397 number = fabs (number);
398 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
399 number = fmod (number, 60. * 60. * 24.);
404 number = fabs (number);
405 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
406 number = fmod (number, 60. * 60.);
409 p += sprintf (p, "%02d", (int) floor (number / 60.));
410 number = fmod (number, 60.);
411 excess_width = format->w - (p - tmp);
412 if (excess_width < 0)
414 if (excess_width == 3 || excess_width == 4
415 || (excess_width >= 5 && format->d == 0))
416 p += sprintf (p, ":%02d", (int) number);
417 else if (excess_width >= 5)
419 int d = MIN (format->d, excess_width - 4);
421 sprintf (p, ":%0*.*f", w, d, number);
422 if (fmt_decimal_char (FMT_F) != '.')
424 char *cp = strchr (p, '.');
426 *cp = fmt_decimal_char (FMT_F);
441 buf_copy_lpad (output, format->w, tmp, p - tmp);
445 output_overflow (format, output);
449 output_missing (format, output);
453 /* Outputs WKDAY format. */
455 output_WKDAY (const union value *input, const struct fmt_spec *format,
458 static const char *weekdays[7] =
460 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
461 "THURSDAY", "FRIDAY", "SATURDAY",
464 if (input->f >= 1 && input->f < 8)
465 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
468 if (input->f != SYSMIS)
469 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
470 output_missing (format, output);
474 /* Outputs MONTH format. */
476 output_MONTH (const union value *input, const struct fmt_spec *format,
479 static const char *months[12] =
481 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
482 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
485 if (input->f >= 1 && input->f < 13)
486 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
489 if (input->f != SYSMIS)
490 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
491 output_missing (format, output);
495 /* Outputs A format. */
497 output_A (const union value *input, const struct fmt_spec *format,
500 memcpy (output, input->s, format->w);
503 /* Outputs AHEX format. */
505 output_AHEX (const union value *input, const struct fmt_spec *format,
508 output_hex (input->s, format->w, output);
511 /* Decimal and scientific formatting. */
513 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
514 increments *WIDTH by REQUEST and return true.
515 Otherwise returns false without changing *WIDTH. */
517 allocate_space (int request, int max_width, int *width)
519 assert (*width <= max_width);
520 if (request + *width <= max_width)
529 /* Tries to compose the number represented by R, in the style of
530 FORMAT, into OUTPUT. Returns true if successful, false on
531 failure, which occurs if FORMAT's width is too narrow. If
532 REQUIRE_AFFIXES is true, then the prefix and suffix specified
533 by FORMAT's style must be included; otherwise, they may be
534 omitted to make the number fit. */
536 output_decimal (const struct rounder *r, const struct fmt_spec *format,
537 bool require_affixes, char *output)
539 const struct fmt_number_style *style = fmt_get_style (format->type);
542 for (decimals = format->d; decimals >= 0; decimals--)
544 /* Formatted version of magnitude of NUMBER. */
547 /* Number of digits in MAGNITUDE's integer and fractional parts. */
550 /* Amount of space within the field width already claimed.
551 Initially this is the width of MAGNITUDE, then it is reduced
552 in stages as space is allocated to prefixes and suffixes and
553 grouping characters. */
556 /* Include various decorations? */
561 /* Position in output. */
564 /* Make sure there's room for the number's magnitude, plus
565 the negative suffix, plus (if negative) the negative
567 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
568 width += ss_length (style->neg_suffix);
570 width += ss_length (style->neg_prefix);
571 if (width > format->w)
574 /* If there's room for the prefix and suffix, allocate
575 space. If the affixes are required, but there's no
577 add_affixes = allocate_space (fmt_affix_width (style),
579 if (!add_affixes && require_affixes)
582 /* Check whether we should include grouping characters.
583 We need room for a complete set or we don't insert any at all.
584 We don't include grouping characters if decimal places were
585 requested but they were all dropped. */
586 add_grouping = (style->grouping != 0
587 && integer_digits > 3
588 && (format->d == 0 || decimals > 0)
589 && allocate_space ((integer_digits - 1) / 3,
592 /* Format the number's magnitude. */
593 rounder_format (r, decimals, magnitude);
595 /* Assemble number. */
597 if (format->w > width)
598 p = mempset (p, ' ', format->w - width);
600 p = mempcpy (p, ss_data (style->neg_prefix),
601 ss_length (style->neg_prefix));
603 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
605 p = mempcpy (p, magnitude, integer_digits);
609 for (i = 0; i < integer_digits; i++)
611 if (i > 0 && (integer_digits - i) % 3 == 0)
612 *p++ = style->grouping;
618 *p++ = style->decimal;
619 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
622 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
624 p = mempcpy (p, ss_data (style->neg_suffix),
625 ss_length (style->neg_suffix));
627 p = mempset (p, ' ', ss_length (style->neg_suffix));
628 assert (p == output + format->w);
635 /* Formats NUMBER into OUTPUT in scientific notation according to
636 the style of the format specified in FORMAT. */
638 output_scientific (double number, const struct fmt_spec *format,
639 bool require_affixes, char *output)
641 const struct fmt_number_style *style = fmt_get_style (format->type);
647 /* Allocate minimum required space. */
648 width = 6 + ss_length (style->neg_suffix);
650 width += ss_length (style->neg_prefix);
651 if (width > format->w)
654 /* Check for room for prefix and suffix. */
655 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
656 if (require_affixes && !add_affixes)
659 /* Figure out number of characters we can use for the fraction,
660 if any. (If that turns out to be 1, then we'll output a
661 decimal point without any digits following; that's what the
662 # flag does in the call to sprintf, below.) */
663 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
664 if (format->type != FMT_E && fraction_width == 1)
666 width += fraction_width;
668 /* Format (except suffix). */
670 if (width < format->w)
671 p = mempset (p, ' ', format->w - width);
673 p = mempcpy (p, ss_data (style->neg_prefix),
674 ss_length (style->neg_prefix));
676 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
677 if (fraction_width > 0)
678 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
680 sprintf (p, "%.0E", fabs (number));
682 /* The C locale always uses a period `.' as a decimal point.
683 Translate to comma if necessary. */
684 if (style->decimal != '.')
686 char *cp = strchr (p, '.');
688 *cp = style->decimal;
691 /* Make exponent have exactly three digits, plus sign. */
693 char *cp = strchr (p, 'E') + 1;
694 long int exponent = strtol (cp, NULL, 10);
695 if (abs (exponent) > 999)
697 sprintf (cp, "%+04ld", exponent);
701 p = strchr (p, '\0');
703 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
705 p = mempcpy (p, ss_data (style->neg_suffix),
706 ss_length (style->neg_suffix));
708 p = mempset (p, ' ', ss_length (style->neg_suffix));
710 assert (p == buf + format->w);
711 memcpy (output, buf, format->w);
717 /* Return X rounded to the nearest integer,
718 rounding ties away from zero. */
722 return x >= 0.0 ? floor (x + .5) : ceil (x - .5);
724 #endif /* !HAVE_ROUND */
726 /* Returns true if the magnitude represented by R should be
727 rounded up when chopped off at DECIMALS decimal places, false
728 if it should be rounded down. */
730 should_round_up (const struct rounder *r, int decimals)
732 int digit = r->string[r->integer_digits + decimals + 1];
733 assert (digit >= '0' && digit <= '9');
737 /* Initializes R for formatting the magnitude of NUMBER to no
738 more than MAX_DECIMAL decimal places. */
740 rounder_init (struct rounder *r, double number, int max_decimals)
742 assert (fabs (number) < 1e41);
743 assert (max_decimals >= 0 && max_decimals <= 16);
744 if (max_decimals == 0)
746 /* Fast path. No rounding needed.
748 We append ".00" to the integer representation because
749 round_up assumes that fractional digits are present. */
750 sprintf (r->string, "%.0f.00", fabs (round (number)));
756 This is more difficult than it really should be because
757 we have to make sure that numbers that are exactly
758 halfway between two representations are always rounded
759 away from zero. This is not what sprintf normally does
760 (usually it rounds to even), so we have to fake it as
761 best we can, by formatting with extra precision and then
762 doing the rounding ourselves.
764 We take up to two rounds to format numbers. In the
765 first round, we obtain 2 digits of precision beyond
766 those requested by the user. If those digits are
767 exactly "50", then in a second round we format with as
768 many digits as are significant in a "double".
770 It might be better to directly implement our own
771 floating-point formatting routine instead of relying on
772 the system's sprintf implementation. But the classic
773 Steele and White paper on printing floating-point
774 numbers does not hint how to do what we want, and it's
775 not obvious how to change their algorithms to do so. It
776 would also be a lot of work. */
777 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
778 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
780 int binary_exponent, decimal_exponent, format_decimals;
781 frexp (number, &binary_exponent);
782 decimal_exponent = binary_exponent * 3 / 10;
783 format_decimals = (DBL_DIG + 1) - decimal_exponent;
784 if (format_decimals > max_decimals + 2)
785 sprintf (r->string, "%.*f", format_decimals, fabs (number));
789 if (r->string[0] == '0')
790 memmove (r->string, &r->string[1], strlen (r->string));
792 r->leading_zeros = strspn (r->string, "0.");
793 r->leading_nines = strspn (r->string, "9.");
794 r->integer_digits = strchr (r->string, '.') - r->string;
795 r->negative = number < 0;
798 /* Returns the number of characters required to format the
799 magnitude represented by R to DECIMALS decimal places.
800 The return value includes integer digits and a decimal point
801 and fractional digits, if any, but it does not include any
802 negative prefix or suffix or other affixes.
804 *INTEGER_DIGITS is set to the number of digits before the
805 decimal point in the output, between 0 and 40.
807 If R represents a negative number and its rounded
808 representation would include at least one nonzero digit,
809 *NEGATIVE is set to true; otherwise, it is set to false. */
811 rounder_width (const struct rounder *r, int decimals,
812 int *integer_digits, bool *negative)
814 /* Calculate base measures. */
815 int width = r->integer_digits;
817 width += decimals + 1;
818 *integer_digits = r->integer_digits;
819 *negative = r->negative;
821 /* Rounding can cause adjustments. */
822 if (should_round_up (r, decimals))
824 /* Rounding up leading 9s adds a new digit (a 1). */
825 if (r->leading_nines >= width)
834 if (r->leading_zeros >= width)
836 /* All digits that remain after rounding are zeros.
837 Therefore we drop the negative sign. */
839 if (r->integer_digits == 0 && decimals == 0)
841 /* No digits at all are left. We need to display
842 at least a single digit (a zero). */
852 /* Formats the magnitude represented by R into OUTPUT, rounding
853 to DECIMALS decimal places. Exactly as many characters as
854 indicated by rounder_width are written. No terminating null
857 rounder_format (const struct rounder *r, int decimals, char *output)
859 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
860 if (should_round_up (r, decimals))
862 if (r->leading_nines < base_width)
864 /* Rounding up. This is the common case where rounding
865 up doesn't add an extra digit. */
867 memcpy (output, r->string, base_width);
868 for (p = output + base_width - 1; ; p--)
870 assert (p >= output);
873 else if (*p >= '0' && *p <= '8')
884 /* Rounding up leading 9s causes the result to be a 1
885 followed by a number of 0s, plus a decimal point. */
888 p = mempset (p, '0', r->integer_digits);
892 p = mempset (p, '0', decimals);
894 assert (p == output + base_width + 1);
900 if (r->integer_digits != 0 || decimals != 0)
902 /* Common case: just copy the digits. */
903 memcpy (output, r->string, base_width);
907 /* No digits remain. The output is just a zero. */
913 /* Helper functions. */
916 static double PURE_FUNCTION
919 static const double p[] =
921 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
922 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
923 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
924 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
927 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
930 /* Returns 256**X. */
931 static double PURE_FUNCTION
934 static const double p[] =
944 18446744073709551616.0
946 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
949 /* Formats non-finite NUMBER into OUTPUT according to the width
952 output_infinite (double number, const struct fmt_spec *format, char *output)
954 assert (!gsl_finite (number));
962 else if (isinf (number))
963 s = number > 0 ? "+Infinity" : "-Infinity";
967 buf_copy_str_lpad (output, format->w, s);
970 output_overflow (format, output);
973 /* Formats OUTPUT as a missing value for the given FORMAT. */
975 output_missing (const struct fmt_spec *format, char *output)
977 memset (output, ' ', format->w);
979 if (format->type != FMT_N)
981 int dot_ofs = (format->type == FMT_PCT ? 2
982 : format->type == FMT_E ? 5
984 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
987 output[format->w - 1] = '.';
990 /* Formats OUTPUT for overflow given FORMAT. */
992 output_overflow (const struct fmt_spec *format, char *output)
994 memset (output, '*', format->w);
997 /* Converts the integer part of NUMBER to a packed BCD number
998 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
999 the least significant nibble of the final byte in OUTPUT is
1000 set to 0. Returns true if successful, false if NUMBER is not
1001 representable. On failure, OUTPUT is cleared to all zero
1004 output_bcd_integer (double number, int digits, char *output)
1008 assert (digits < sizeof decimal);
1009 if (number != SYSMIS
1011 && number < power10 (digits)
1012 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1014 const char *src = decimal;
1017 for (i = 0; i < digits / 2; i++)
1019 int d0 = *src++ - '0';
1020 int d1 = *src++ - '0';
1021 *output++ = (d0 << 4) + d1;
1024 *output = (*src - '0') << 4;
1030 memset (output, 0, DIV_RND_UP (digits, 2));
1035 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1036 given INTEGER_FORMAT. */
1038 output_binary_integer (uint64_t value, int bytes,
1039 enum integer_format integer_format, char *output)
1041 integer_put (value, integer_format, output, bytes);
1044 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1045 digits in OUTPUT. */
1047 output_hex (const void *data_, size_t bytes, char *output)
1049 const uint8_t *data = data_;
1052 for (i = 0; i < bytes; i++)
1054 static const char hex_digits[] = "0123456789ABCDEF";
1055 *output++ = hex_digits[data[i] >> 4];
1056 *output++ = hex_digits[data[i] & 15];