1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include <gsl/gsl_math.h>
37 #include <libpspp/assertion.h>
38 #include <libpspp/float-format.h>
39 #include <libpspp/integer-format.h>
40 #include <libpspp/magic.h>
41 #include <libpspp/message.h>
42 #include <libpspp/misc.h>
43 #include <libpspp/misc.h>
44 #include <libpspp/str.h>
49 #define _(msgid) gettext (msgid)
51 /* A representation of a number that can be quickly rounded to
52 any desired number of decimal places (up to a specified
56 char string[64]; /* Magnitude of number with excess precision. */
57 int integer_digits; /* Number of digits before decimal point. */
58 int leading_nines; /* Number of `9's or `.'s at start of string. */
59 int leading_zeros; /* Number of `0's or `.'s at start of string. */
60 bool negative; /* Is the number negative? */
63 static void rounder_init (struct rounder *, double number, int max_decimals);
64 static int rounder_width (const struct rounder *, int decimals,
65 int *integer_digits, bool *negative);
66 static void rounder_format (const struct rounder *, int decimals,
69 /* Format of integers in output (SET WIB). */
70 static enum integer_format output_integer_format = INTEGER_NATIVE;
72 /* Format of reals in output (SET WRB). */
73 static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE;
75 typedef void data_out_converter_func (const union value *,
76 const struct fmt_spec *,
78 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
79 static data_out_converter_func output_##METHOD;
82 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
83 bool require_affixes, char *);
84 static bool output_scientific (double, const struct fmt_spec *,
85 bool require_affixes, char *);
87 static double power10 (int) PURE_FUNCTION;
88 static double power256 (int) PURE_FUNCTION;
90 static void output_infinite (double, const struct fmt_spec *, char *);
91 static void output_missing (const struct fmt_spec *, char *);
92 static void output_overflow (const struct fmt_spec *, char *);
93 static bool output_bcd_integer (double, int digits, char *);
94 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
96 static void output_hex (const void *, size_t bytes, char *);
98 /* Converts the INPUT value into printable form in the exactly
99 FORMAT->W characters in OUTPUT according to format
100 specification FORMAT. No null terminator is appended to the
103 data_out (const union value *input, const struct fmt_spec *format,
106 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
108 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
109 #include "format.def"
112 assert (fmt_check_output (format));
114 converters[format->type] (input, format, output);
117 /* Returns the current output integer format. */
119 data_out_get_integer_format (void)
121 return output_integer_format;
124 /* Sets the output integer format to INTEGER_FORMAT. */
126 data_out_set_integer_format (enum integer_format integer_format)
128 output_integer_format = integer_format;
131 /* Returns the current output float format. */
133 data_out_get_float_format (void)
135 return output_float_format;
138 /* Sets the output float format to FLOAT_FORMAT. */
140 data_out_set_float_format (enum float_format float_format)
142 output_float_format = float_format;
145 /* Main conversion functions. */
147 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
150 output_number (const union value *input, const struct fmt_spec *format,
153 double number = input->f;
155 if (number == SYSMIS)
156 output_missing (format, output);
157 else if (!gsl_finite (number))
158 output_infinite (number, format, output);
161 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
164 rounder_init (&r, number, format->d);
166 if (output_decimal (&r, format, true, output)
167 || output_scientific (number, format, true, output)
168 || output_decimal (&r, format, false, output))
172 if (!output_scientific (number, format, false, output))
173 output_overflow (format, output);
177 /* Outputs N format. */
179 output_N (const union value *input, const struct fmt_spec *format,
182 double number = input->f * power10 (format->d);
183 if (input->f == SYSMIS || number < 0)
184 output_missing (format, output);
188 number = fabs (round (number));
189 if (number < power10 (format->w)
190 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
191 memcpy (output, buf, format->w);
193 output_overflow (format, output);
197 /* Outputs Z format. */
199 output_Z (const union value *input, const struct fmt_spec *format,
202 double number = input->f * power10 (format->d);
204 if (input->f == SYSMIS)
205 output_missing (format, output);
206 else if (fabs (number) >= power10 (format->w)
207 || sprintf (buf, "%0*.0f", format->w,
208 fabs (round (number))) != format->w)
209 output_overflow (format, output);
212 if (number < 0 && strspn (buf, "0") < format->w)
214 char *p = &buf[format->w - 1];
215 *p = "}JKLMNOPQR"[*p - '0'];
217 memcpy (output, buf, format->w);
221 /* Outputs P format. */
223 output_P (const union value *input, const struct fmt_spec *format,
226 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
227 format->w * 2 - 1, output)
229 output[format->w - 1] |= 0xd;
231 output[format->w - 1] |= 0xf;
234 /* Outputs PK format. */
236 output_PK (const union value *input, const struct fmt_spec *format,
239 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
242 /* Outputs IB format. */
244 output_IB (const union value *input, const struct fmt_spec *format,
247 double number = round (input->f * power10 (format->d));
248 if (input->f == SYSMIS
249 || number >= power256 (format->w) / 2 - 1
250 || number < -power256 (format->w) / 2)
251 memset (output, 0, format->w);
254 uint64_t integer = fabs (number);
257 output_binary_integer (integer, format->w, output_integer_format,
262 /* Outputs PIB format. */
264 output_PIB (const union value *input, const struct fmt_spec *format,
267 double number = round (input->f * power10 (format->d));
268 if (input->f == SYSMIS
269 || number < 0 || number >= power256 (format->w))
270 memset (output, 0, format->w);
272 output_binary_integer (number, format->w, output_integer_format, output);
275 /* Outputs PIBHEX format. */
277 output_PIBHEX (const union value *input, const struct fmt_spec *format,
280 double number = round (input->f);
281 if (input->f == SYSMIS)
282 output_missing (format, output);
283 else if (input->f < 0 || number >= power256 (format->w / 2))
284 output_overflow (format, output);
288 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
289 output_hex (tmp, format->w / 2, output);
293 /* Outputs RB format. */
295 output_RB (const union value *input, const struct fmt_spec *format,
299 memcpy (output, &d, format->w);
302 /* Outputs RBHEX format. */
304 output_RBHEX (const union value *input, const struct fmt_spec *format,
308 output_hex (&d, format->w / 2, output);
311 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
312 DATETIME, TIME, and DTIME formats. */
314 output_date (const union value *input, const struct fmt_spec *format,
317 double number = input->f;
318 int year, month, day, yday;
320 const char *template = fmt_date_template (format->type);
321 size_t template_width = strlen (template);
322 int excess_width = format->w - template_width;
327 assert (format->w >= template_width);
328 if (number == SYSMIS)
331 if (fmt_get_category (format->type) == FMT_CAT_DATE)
335 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
336 &year, &month, &day, &yday);
337 number = fmod (number, 60. * 60. * 24.);
340 year = month = day = yday = 0;
342 while (*template != '\0')
346 while (template[count] == ch)
354 p += sprintf (p, "%02d", day);
356 p += sprintf (p, "%03d", yday);
360 p += sprintf (p, "%02d", month);
363 static const char *months[12] =
365 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
366 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
368 p = stpcpy (p, months[month - 1]);
372 if (count >= 4 || excess_width >= 2)
375 p += sprintf (p, "%04d", year);
376 else if (format->type == FMT_DATETIME)
377 p = stpcpy (p, "****");
383 int offset = year - get_epoch ();
384 if (offset < 0 || offset > 99)
386 p += sprintf (p, "%02d", abs (year) % 100);
390 p += sprintf (p, "%d", (month - 1) / 3 + 1);
393 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
398 number = fabs (number);
399 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
400 number = fmod (number, 60. * 60. * 24.);
405 number = fabs (number);
406 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
407 number = fmod (number, 60. * 60.);
410 p += sprintf (p, "%02d", (int) floor (number / 60.));
411 number = fmod (number, 60.);
412 excess_width = format->w - (p - tmp);
413 if (excess_width < 0)
415 if (excess_width == 3 || excess_width == 4
416 || (excess_width >= 5 && format->d == 0))
417 p += sprintf (p, ":%02d", (int) number);
418 else if (excess_width >= 5)
420 int d = MIN (format->d, excess_width - 4);
422 sprintf (p, ":%0*.*f", w, d, number);
423 if (fmt_decimal_char (FMT_F) != '.')
425 char *cp = strchr (p, '.');
427 *cp = fmt_decimal_char (FMT_F);
442 buf_copy_lpad (output, format->w, tmp, p - tmp);
446 output_overflow (format, output);
450 output_missing (format, output);
454 /* Outputs WKDAY format. */
456 output_WKDAY (const union value *input, const struct fmt_spec *format,
459 static const char *weekdays[7] =
461 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
462 "THURSDAY", "FRIDAY", "SATURDAY",
465 if (input->f >= 1 && input->f < 8)
466 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
469 if (input->f != SYSMIS)
470 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
471 output_missing (format, output);
475 /* Outputs MONTH format. */
477 output_MONTH (const union value *input, const struct fmt_spec *format,
480 static const char *months[12] =
482 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
483 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
486 if (input->f >= 1 && input->f < 13)
487 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
490 if (input->f != SYSMIS)
491 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
492 output_missing (format, output);
496 /* Outputs A format. */
498 output_A (const union value *input, const struct fmt_spec *format,
501 memcpy (output, input->s, format->w);
504 /* Outputs AHEX format. */
506 output_AHEX (const union value *input, const struct fmt_spec *format,
509 output_hex (input->s, format->w, output);
512 /* Decimal and scientific formatting. */
514 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
515 increments *WIDTH by REQUEST and return true.
516 Otherwise returns false without changing *WIDTH. */
518 allocate_space (int request, int max_width, int *width)
520 assert (*width <= max_width);
521 if (request + *width <= max_width)
530 /* Tries to compose the number represented by R, in the style of
531 FORMAT, into OUTPUT. Returns true if successful, false on
532 failure, which occurs if FORMAT's width is too narrow. If
533 REQUIRE_AFFIXES is true, then the prefix and suffix specified
534 by FORMAT's style must be included; otherwise, they may be
535 omitted to make the number fit. */
537 output_decimal (const struct rounder *r, const struct fmt_spec *format,
538 bool require_affixes, char *output)
540 const struct fmt_number_style *style = fmt_get_style (format->type);
543 for (decimals = format->d; decimals >= 0; decimals--)
545 /* Formatted version of magnitude of NUMBER. */
548 /* Number of digits in MAGNITUDE's integer and fractional parts. */
551 /* Amount of space within the field width already claimed.
552 Initially this is the width of MAGNITUDE, then it is reduced
553 in stages as space is allocated to prefixes and suffixes and
554 grouping characters. */
557 /* Include various decorations? */
562 /* Position in output. */
565 /* Make sure there's room for the number's magnitude, plus
566 the negative suffix, plus (if negative) the negative
568 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
569 width += ss_length (style->neg_suffix);
571 width += ss_length (style->neg_prefix);
572 if (width > format->w)
575 /* If there's room for the prefix and suffix, allocate
576 space. If the affixes are required, but there's no
578 add_affixes = allocate_space (fmt_affix_width (style),
580 if (!add_affixes && require_affixes)
583 /* Check whether we should include grouping characters.
584 We need room for a complete set or we don't insert any at all.
585 We don't include grouping characters if decimal places were
586 requested but they were all dropped. */
587 add_grouping = (style->grouping != 0
588 && integer_digits > 3
589 && (format->d == 0 || decimals > 0)
590 && allocate_space ((integer_digits - 1) / 3,
593 /* Format the number's magnitude. */
594 rounder_format (r, decimals, magnitude);
596 /* Assemble number. */
598 if (format->w > width)
599 p = mempset (p, ' ', format->w - width);
601 p = mempcpy (p, ss_data (style->neg_prefix),
602 ss_length (style->neg_prefix));
604 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
606 p = mempcpy (p, magnitude, integer_digits);
610 for (i = 0; i < integer_digits; i++)
612 if (i > 0 && (integer_digits - i) % 3 == 0)
613 *p++ = style->grouping;
619 *p++ = style->decimal;
620 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
623 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
625 p = mempcpy (p, ss_data (style->neg_suffix),
626 ss_length (style->neg_suffix));
628 p = mempset (p, ' ', ss_length (style->neg_suffix));
629 assert (p == output + format->w);
636 /* Formats NUMBER into OUTPUT in scientific notation according to
637 the style of the format specified in FORMAT. */
639 output_scientific (double number, const struct fmt_spec *format,
640 bool require_affixes, char *output)
642 const struct fmt_number_style *style = fmt_get_style (format->type);
648 /* Allocate minimum required space. */
649 width = 6 + ss_length (style->neg_suffix);
651 width += ss_length (style->neg_prefix);
652 if (width > format->w)
655 /* Check for room for prefix and suffix. */
656 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
657 if (require_affixes && !add_affixes)
660 /* Figure out number of characters we can use for the fraction,
661 if any. (If that turns out to be 1, then we'll output a
662 decimal point without any digits following; that's what the
663 # flag does in the call to sprintf, below.) */
664 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
665 if (format->type != FMT_E && fraction_width == 1)
667 width += fraction_width;
669 /* Format (except suffix). */
671 if (width < format->w)
672 p = mempset (p, ' ', format->w - width);
674 p = mempcpy (p, ss_data (style->neg_prefix),
675 ss_length (style->neg_prefix));
677 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
678 if (fraction_width > 0)
679 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
681 sprintf (p, "%.0E", fabs (number));
683 /* The C locale always uses a period `.' as a decimal point.
684 Translate to comma if necessary. */
685 if (style->decimal != '.')
687 char *cp = strchr (p, '.');
689 *cp = style->decimal;
692 /* Make exponent have exactly three digits, plus sign. */
694 char *cp = strchr (p, 'E') + 1;
695 long int exponent = strtol (cp, NULL, 10);
696 if (abs (exponent) > 999)
698 sprintf (cp, "%+04ld", exponent);
702 p = strchr (p, '\0');
704 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
706 p = mempcpy (p, ss_data (style->neg_suffix),
707 ss_length (style->neg_suffix));
709 p = mempset (p, ' ', ss_length (style->neg_suffix));
711 assert (p == buf + format->w);
713 buf_copy_str_lpad (output, format->w, buf);
718 /* Return X rounded to the nearest integer,
719 rounding ties away from zero. */
723 return x >= 0.0 ? floor (x + .5) : ceil (x - .5);
725 #endif /* !HAVE_ROUND */
727 /* Returns true if the magnitude represented by R should be
728 rounded up when chopped off at DECIMALS decimal places, false
729 if it should be rounded down. */
731 should_round_up (const struct rounder *r, int decimals)
733 int digit = r->string[r->integer_digits + decimals + 1];
734 assert (digit >= '0' && digit <= '9');
738 /* Initializes R for formatting the magnitude of NUMBER to no
739 more than MAX_DECIMAL decimal places. */
741 rounder_init (struct rounder *r, double number, int max_decimals)
743 assert (fabs (number) < 1e41);
744 assert (max_decimals >= 0 && max_decimals <= 16);
745 if (max_decimals == 0)
747 /* Fast path. No rounding needed.
749 We append ".00" to the integer representation because
750 round_up assumes that fractional digits are present. */
751 sprintf (r->string, "%.0f.00", fabs (round (number)));
757 This is more difficult than it really should be because
758 we have to make sure that numbers that are exactly
759 halfway between two representations are always rounded
760 away from zero. This is not what sprintf normally does
761 (usually it rounds to even), so we have to fake it as
762 best we can, by formatting with extra precision and then
763 doing the rounding ourselves.
765 We take up to two rounds to format numbers. In the
766 first round, we obtain 2 digits of precision beyond
767 those requested by the user. If those digits are
768 exactly "50", then in a second round we format with as
769 many digits as are significant in a "double".
771 It might be better to directly implement our own
772 floating-point formatting routine instead of relying on
773 the system's sprintf implementation. But the classic
774 Steele and White paper on printing floating-point
775 numbers does not hint how to do what we want, and it's
776 not obvious how to change their algorithms to do so. It
777 would also be a lot of work. */
778 sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
779 if (!strcmp (r->string + strlen (r->string) - 2, "50"))
781 int binary_exponent, decimal_exponent, format_decimals;
782 frexp (number, &binary_exponent);
783 decimal_exponent = binary_exponent * 3 / 10;
784 format_decimals = (DBL_DIG + 1) - decimal_exponent;
785 if (format_decimals > max_decimals + 2)
786 sprintf (r->string, "%.*f", format_decimals, fabs (number));
790 if (r->string[0] == '0')
791 memmove (r->string, &r->string[1], strlen (r->string));
793 r->leading_zeros = strspn (r->string, "0.");
794 r->leading_nines = strspn (r->string, "9.");
795 r->integer_digits = strchr (r->string, '.') - r->string;
796 r->negative = number < 0;
799 /* Returns the number of characters required to format the
800 magnitude represented by R to DECIMALS decimal places.
801 The return value includes integer digits and a decimal point
802 and fractional digits, if any, but it does not include any
803 negative prefix or suffix or other affixes.
805 *INTEGER_DIGITS is set to the number of digits before the
806 decimal point in the output, between 0 and 40.
808 If R represents a negative number and its rounded
809 representation would include at least one nonzero digit,
810 *NEGATIVE is set to true; otherwise, it is set to false. */
812 rounder_width (const struct rounder *r, int decimals,
813 int *integer_digits, bool *negative)
815 /* Calculate base measures. */
816 int width = r->integer_digits;
818 width += decimals + 1;
819 *integer_digits = r->integer_digits;
820 *negative = r->negative;
822 /* Rounding can cause adjustments. */
823 if (should_round_up (r, decimals))
825 /* Rounding up leading 9s adds a new digit (a 1). */
826 if (r->leading_nines >= width)
835 if (r->leading_zeros >= width)
837 /* All digits that remain after rounding are zeros.
838 Therefore we drop the negative sign. */
840 if (r->integer_digits == 0 && decimals == 0)
842 /* No digits at all are left. We need to display
843 at least a single digit (a zero). */
853 /* Formats the magnitude represented by R into OUTPUT, rounding
854 to DECIMALS decimal places. Exactly as many characters as
855 indicated by rounder_width are written. No terminating null
858 rounder_format (const struct rounder *r, int decimals, char *output)
860 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
861 if (should_round_up (r, decimals))
863 if (r->leading_nines < base_width)
865 /* Rounding up. This is the common case where rounding
866 up doesn't add an extra digit. */
868 memcpy (output, r->string, base_width);
869 for (p = output + base_width - 1; ; p--)
871 assert (p >= output);
874 else if (*p >= '0' && *p <= '8')
885 /* Rounding up leading 9s causes the result to be a 1
886 followed by a number of 0s, plus a decimal point. */
889 p = mempset (p, '0', r->integer_digits);
893 p = mempset (p, '0', decimals);
895 assert (p == output + base_width + 1);
901 if (r->integer_digits != 0 || decimals != 0)
903 /* Common case: just copy the digits. */
904 memcpy (output, r->string, base_width);
908 /* No digits remain. The output is just a zero. */
914 /* Helper functions. */
917 static double PURE_FUNCTION
920 static const double p[] =
922 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
923 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
924 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
925 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
928 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
931 /* Returns 256**X. */
932 static double PURE_FUNCTION
935 static const double p[] =
945 18446744073709551616.0
947 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
950 /* Formats non-finite NUMBER into OUTPUT according to the width
953 output_infinite (double number, const struct fmt_spec *format, char *output)
955 assert (!gsl_finite (number));
963 else if (isinf (number))
964 s = number > 0 ? "+Infinity" : "-Infinity";
968 buf_copy_str_lpad (output, format->w, s);
971 output_overflow (format, output);
974 /* Formats OUTPUT as a missing value for the given FORMAT. */
976 output_missing (const struct fmt_spec *format, char *output)
978 memset (output, ' ', format->w);
980 if (format->type != FMT_N)
982 int dot_ofs = (format->type == FMT_PCT ? 2
983 : format->type == FMT_E ? 5
985 output[MAX (0, format->w - format->d - dot_ofs)] = '.';
988 output[format->w - 1] = '.';
991 /* Formats OUTPUT for overflow given FORMAT. */
993 output_overflow (const struct fmt_spec *format, char *output)
995 memset (output, '*', format->w);
998 /* Converts the integer part of NUMBER to a packed BCD number
999 with the given number of DIGITS in OUTPUT. If DIGITS is odd,
1000 the least significant nibble of the final byte in OUTPUT is
1001 set to 0. Returns true if successful, false if NUMBER is not
1002 representable. On failure, OUTPUT is cleared to all zero
1005 output_bcd_integer (double number, int digits, char *output)
1009 assert (digits < sizeof decimal);
1010 if (number != SYSMIS
1012 && number < power10 (digits)
1013 && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1015 const char *src = decimal;
1018 for (i = 0; i < digits / 2; i++)
1020 int d0 = *src++ - '0';
1021 int d1 = *src++ - '0';
1022 *output++ = (d0 << 4) + d1;
1025 *output = (*src - '0') << 4;
1031 memset (output, 0, DIV_RND_UP (digits, 2));
1036 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1037 given INTEGER_FORMAT. */
1039 output_binary_integer (uint64_t value, int bytes,
1040 enum integer_format integer_format, char *output)
1042 integer_put (value, integer_format, output, bytes);
1045 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1046 digits in OUTPUT. */
1048 output_hex (const void *data_, size_t bytes, char *output)
1050 const uint8_t *data = data_;
1053 for (i = 0; i < bytes; i++)
1055 static const char hex_digits[] = "0123456789ABCDEF";
1056 *output++ = hex_digits[data[i] >> 4];
1057 *output++ = hex_digits[data[i] & 15];