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/>. */
28 #include <data/calendar.h>
29 #include <data/format.h>
30 #include <data/settings.h>
31 #include <data/value.h>
33 #include <libpspp/assertion.h>
34 #include <libpspp/float-format.h>
35 #include <libpspp/integer-format.h>
36 #include <libpspp/message.h>
37 #include <libpspp/misc.h>
38 #include <libpspp/str.h>
43 #define _(msgid) gettext (msgid)
45 /* A representation of a number that can be quickly rounded to
46 any desired number of decimal places (up to a specified
50 char string[64]; /* Magnitude of number with excess precision. */
51 int integer_digits; /* Number of digits before decimal point. */
52 int leading_nines; /* Number of `9's or `.'s at start of string. */
53 int leading_zeros; /* Number of `0's or `.'s at start of string. */
54 bool negative; /* Is the number negative? */
57 static void rounder_init (struct rounder *, double number, int max_decimals);
58 static int rounder_width (const struct rounder *, int decimals,
59 int *integer_digits, bool *negative);
60 static void rounder_format (const struct rounder *, int decimals,
63 /* Format of integers in output (SET WIB). */
64 static enum integer_format output_integer_format = INTEGER_NATIVE;
66 /* Format of reals in output (SET WRB). */
67 static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE;
69 typedef void data_out_converter_func (const union value *,
70 const struct fmt_spec *,
72 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
73 static data_out_converter_func output_##METHOD;
76 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
77 bool require_affixes, char *);
78 static bool output_scientific (double, const struct fmt_spec *,
79 bool require_affixes, char *);
81 static double power10 (int) PURE_FUNCTION;
82 static double power256 (int) PURE_FUNCTION;
84 static void output_infinite (double, const struct fmt_spec *, char *);
85 static void output_missing (const struct fmt_spec *, char *);
86 static void output_overflow (const struct fmt_spec *, char *);
87 static bool output_bcd_integer (double, int digits, char *);
88 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
90 static void output_hex (const void *, size_t bytes, char *);
92 /* Converts the INPUT value into printable form in the exactly
93 FORMAT->W characters in OUTPUT according to format
94 specification FORMAT. The output is recoded from native form
95 into the given legacy character ENCODING. No null terminator
96 is appended to the buffer. */
98 data_out_legacy (const union value *input, enum legacy_encoding encoding,
99 const struct fmt_spec *format, char *output)
101 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
103 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
104 #include "format.def"
107 assert (fmt_check_output (format));
109 converters[format->type] (input, format, output);
110 if (encoding != LEGACY_NATIVE
111 && fmt_get_category (format->type) != FMT_CAT_BINARY)
112 legacy_recode (LEGACY_NATIVE, output, encoding, output, format->w);
115 /* Same as data_out_legacy with ENCODING set to LEGACY_NATIVE. */
117 data_out (const union value *value, const struct fmt_spec *format,
120 return data_out_legacy (value, LEGACY_NATIVE, format, output);
123 /* Returns the current output integer format. */
125 data_out_get_integer_format (void)
127 return output_integer_format;
130 /* Sets the output integer format to INTEGER_FORMAT. */
132 data_out_set_integer_format (enum integer_format integer_format)
134 output_integer_format = integer_format;
137 /* Returns the current output float format. */
139 data_out_get_float_format (void)
141 return output_float_format;
144 /* Sets the output float format to FLOAT_FORMAT. */
146 data_out_set_float_format (enum float_format float_format)
148 output_float_format = float_format;
151 /* Main conversion functions. */
153 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
156 output_number (const union value *input, const struct fmt_spec *format,
159 double number = input->f;
161 if (number == SYSMIS)
162 output_missing (format, output);
163 else if (!isfinite (number))
164 output_infinite (number, format, output);
167 if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
170 rounder_init (&r, number, format->d);
172 if (output_decimal (&r, format, true, output)
173 || output_scientific (number, format, true, output)
174 || output_decimal (&r, format, false, output))
178 if (!output_scientific (number, format, false, output))
179 output_overflow (format, output);
183 /* Outputs N format. */
185 output_N (const union value *input, const struct fmt_spec *format,
188 double number = input->f * power10 (format->d);
189 if (input->f == SYSMIS || number < 0)
190 output_missing (format, output);
194 number = fabs (round (number));
195 if (number < power10 (format->w)
196 && sprintf (buf, "%0*.0f", format->w, number) == format->w)
197 memcpy (output, buf, format->w);
199 output_overflow (format, output);
203 /* Outputs Z format. */
205 output_Z (const union value *input, const struct fmt_spec *format,
208 double number = input->f * power10 (format->d);
210 if (input->f == SYSMIS)
211 output_missing (format, output);
212 else if (fabs (number) >= power10 (format->w)
213 || sprintf (buf, "%0*.0f", format->w,
214 fabs (round (number))) != format->w)
215 output_overflow (format, output);
218 if (number < 0 && strspn (buf, "0") < format->w)
220 char *p = &buf[format->w - 1];
221 *p = "}JKLMNOPQR"[*p - '0'];
223 memcpy (output, buf, format->w);
227 /* Outputs P format. */
229 output_P (const union value *input, const struct fmt_spec *format,
232 if (output_bcd_integer (fabs (input->f * power10 (format->d)),
233 format->w * 2 - 1, output)
235 output[format->w - 1] |= 0xd;
237 output[format->w - 1] |= 0xf;
240 /* Outputs PK format. */
242 output_PK (const union value *input, const struct fmt_spec *format,
245 output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
248 /* Outputs IB format. */
250 output_IB (const union value *input, const struct fmt_spec *format,
253 double number = round (input->f * power10 (format->d));
254 if (input->f == SYSMIS
255 || number >= power256 (format->w) / 2 - 1
256 || number < -power256 (format->w) / 2)
257 memset (output, 0, format->w);
260 uint64_t integer = fabs (number);
263 output_binary_integer (integer, format->w, output_integer_format,
268 /* Outputs PIB format. */
270 output_PIB (const union value *input, const struct fmt_spec *format,
273 double number = round (input->f * power10 (format->d));
274 if (input->f == SYSMIS
275 || number < 0 || number >= power256 (format->w))
276 memset (output, 0, format->w);
278 output_binary_integer (number, format->w, output_integer_format, output);
281 /* Outputs PIBHEX format. */
283 output_PIBHEX (const union value *input, const struct fmt_spec *format,
286 double number = round (input->f);
287 if (input->f == SYSMIS)
288 output_missing (format, output);
289 else if (input->f < 0 || number >= power256 (format->w / 2))
290 output_overflow (format, output);
294 output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
295 output_hex (tmp, format->w / 2, output);
299 /* Outputs RB format. */
301 output_RB (const union value *input, const struct fmt_spec *format,
305 memcpy (output, &d, format->w);
308 /* Outputs RBHEX format. */
310 output_RBHEX (const union value *input, const struct fmt_spec *format,
314 output_hex (&d, format->w / 2, output);
317 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
318 DATETIME, TIME, and DTIME formats. */
320 output_date (const union value *input, const struct fmt_spec *format,
323 double number = input->f;
324 int year, month, day, yday;
326 const char *template = fmt_date_template (format->type);
327 size_t template_width = strlen (template);
328 int excess_width = format->w - template_width;
333 assert (format->w >= template_width);
334 if (number == SYSMIS)
337 if (fmt_get_category (format->type) == FMT_CAT_DATE)
341 calendar_offset_to_gregorian (number / 60. / 60. / 24.,
342 &year, &month, &day, &yday);
343 number = fmod (number, 60. * 60. * 24.);
346 year = month = day = yday = 0;
348 while (*template != '\0')
352 while (template[count] == ch)
360 p += sprintf (p, "%02d", day);
362 p += sprintf (p, "%03d", yday);
366 p += sprintf (p, "%02d", month);
369 static const char *months[12] =
371 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
372 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
374 p = stpcpy (p, months[month - 1]);
378 if (count >= 4 || excess_width >= 2)
381 p += sprintf (p, "%04d", year);
382 else if (format->type == FMT_DATETIME)
383 p = stpcpy (p, "****");
389 int offset = year - get_epoch ();
390 if (offset < 0 || offset > 99)
392 p += sprintf (p, "%02d", abs (year) % 100);
396 p += sprintf (p, "%d", (month - 1) / 3 + 1);
399 p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
404 number = fabs (number);
405 p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
406 number = fmod (number, 60. * 60. * 24.);
411 number = fabs (number);
412 p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
413 number = fmod (number, 60. * 60.);
416 p += sprintf (p, "%02d", (int) floor (number / 60.));
417 number = fmod (number, 60.);
418 excess_width = format->w - (p - tmp);
419 if (excess_width < 0)
421 if (excess_width == 3 || excess_width == 4
422 || (excess_width >= 5 && format->d == 0))
423 p += sprintf (p, ":%02d", (int) number);
424 else if (excess_width >= 5)
426 int d = MIN (format->d, excess_width - 4);
428 sprintf (p, ":%0*.*f", w, d, number);
429 if (fmt_decimal_char (FMT_F) != '.')
431 char *cp = strchr (p, '.');
433 *cp = fmt_decimal_char (FMT_F);
448 buf_copy_lpad (output, format->w, tmp, p - tmp);
452 output_overflow (format, output);
456 output_missing (format, output);
460 /* Outputs WKDAY format. */
462 output_WKDAY (const union value *input, const struct fmt_spec *format,
465 static const char *weekdays[7] =
467 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
468 "THURSDAY", "FRIDAY", "SATURDAY",
471 if (input->f >= 1 && input->f < 8)
472 buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]);
475 if (input->f != SYSMIS)
476 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
477 output_missing (format, output);
481 /* Outputs MONTH format. */
483 output_MONTH (const union value *input, const struct fmt_spec *format,
486 static const char *months[12] =
488 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
489 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
492 if (input->f >= 1 && input->f < 13)
493 buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]);
496 if (input->f != SYSMIS)
497 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
498 output_missing (format, output);
502 /* Outputs A format. */
504 output_A (const union value *input, const struct fmt_spec *format,
507 memcpy (output, input->s, format->w);
510 /* Outputs AHEX format. */
512 output_AHEX (const union value *input, const struct fmt_spec *format,
515 output_hex (input->s, format->w, output);
518 /* Decimal and scientific formatting. */
520 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
521 increments *WIDTH by REQUEST and return true.
522 Otherwise returns false without changing *WIDTH. */
524 allocate_space (int request, int max_width, int *width)
526 assert (*width <= max_width);
527 if (request + *width <= max_width)
536 /* Tries to compose the number represented by R, in the style of
537 FORMAT, into OUTPUT. Returns true if successful, false on
538 failure, which occurs if FORMAT's width is too narrow. If
539 REQUIRE_AFFIXES is true, then the prefix and suffix specified
540 by FORMAT's style must be included; otherwise, they may be
541 omitted to make the number fit. */
543 output_decimal (const struct rounder *r, const struct fmt_spec *format,
544 bool require_affixes, char *output)
546 const struct fmt_number_style *style = fmt_get_style (format->type);
549 for (decimals = format->d; decimals >= 0; decimals--)
551 /* Formatted version of magnitude of NUMBER. */
554 /* Number of digits in MAGNITUDE's integer and fractional parts. */
557 /* Amount of space within the field width already claimed.
558 Initially this is the width of MAGNITUDE, then it is reduced
559 in stages as space is allocated to prefixes and suffixes and
560 grouping characters. */
563 /* Include various decorations? */
568 /* Position in output. */
571 /* Make sure there's room for the number's magnitude, plus
572 the negative suffix, plus (if negative) the negative
574 width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
575 width += ss_length (style->neg_suffix);
577 width += ss_length (style->neg_prefix);
578 if (width > format->w)
581 /* If there's room for the prefix and suffix, allocate
582 space. If the affixes are required, but there's no
584 add_affixes = allocate_space (fmt_affix_width (style),
586 if (!add_affixes && require_affixes)
589 /* Check whether we should include grouping characters.
590 We need room for a complete set or we don't insert any at all.
591 We don't include grouping characters if decimal places were
592 requested but they were all dropped. */
593 add_grouping = (style->grouping != 0
594 && integer_digits > 3
595 && (format->d == 0 || decimals > 0)
596 && allocate_space ((integer_digits - 1) / 3,
599 /* Format the number's magnitude. */
600 rounder_format (r, decimals, magnitude);
602 /* Assemble number. */
604 if (format->w > width)
605 p = mempset (p, ' ', format->w - width);
607 p = mempcpy (p, ss_data (style->neg_prefix),
608 ss_length (style->neg_prefix));
610 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
612 p = mempcpy (p, magnitude, integer_digits);
616 for (i = 0; i < integer_digits; i++)
618 if (i > 0 && (integer_digits - i) % 3 == 0)
619 *p++ = style->grouping;
625 *p++ = style->decimal;
626 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
629 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
631 p = mempcpy (p, ss_data (style->neg_suffix),
632 ss_length (style->neg_suffix));
634 p = mempset (p, ' ', ss_length (style->neg_suffix));
635 assert (p == output + format->w);
642 /* Formats NUMBER into OUTPUT in scientific notation according to
643 the style of the format specified in FORMAT. */
645 output_scientific (double number, const struct fmt_spec *format,
646 bool require_affixes, char *output)
648 const struct fmt_number_style *style = fmt_get_style (format->type);
654 /* Allocate minimum required space. */
655 width = 6 + ss_length (style->neg_suffix);
657 width += ss_length (style->neg_prefix);
658 if (width > format->w)
661 /* Check for room for prefix and suffix. */
662 add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
663 if (require_affixes && !add_affixes)
666 /* Figure out number of characters we can use for the fraction,
667 if any. (If that turns out to be 1, then we'll output a
668 decimal point without any digits following; that's what the
669 # flag does in the call to sprintf, below.) */
670 fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
671 if (format->type != FMT_E && fraction_width == 1)
673 width += fraction_width;
675 /* Format (except suffix). */
677 if (width < format->w)
678 p = mempset (p, ' ', format->w - width);
680 p = mempcpy (p, ss_data (style->neg_prefix),
681 ss_length (style->neg_prefix));
683 p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
684 if (fraction_width > 0)
685 sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
687 sprintf (p, "%.0E", fabs (number));
689 /* The C locale always uses a period `.' as a decimal point.
690 Translate to comma if necessary. */
691 if (style->decimal != '.')
693 char *cp = strchr (p, '.');
695 *cp = style->decimal;
698 /* Make exponent have exactly three digits, plus sign. */
700 char *cp = strchr (p, 'E') + 1;
701 long int exponent = strtol (cp, NULL, 10);
702 if (abs (exponent) > 999)
704 sprintf (cp, "%+04ld", exponent);
708 p = strchr (p, '\0');
710 p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
712 p = mempcpy (p, ss_data (style->neg_suffix),
713 ss_length (style->neg_suffix));
715 p = mempset (p, ' ', ss_length (style->neg_suffix));
717 assert (p == buf + format->w);
718 memcpy (output, buf, format->w);
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 (!isfinite (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];