w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

utilnumber.c
Go to the documentation of this file.
1 
2 #include <math.h> /* for log10() and floor() */
3 #include <stdio.h> /* for printf() */
4 
5 #include "utilnumber.h"
6 
7 // todo: lookups can be chars
8 // change lookup arrays to some __name to discourage accessing them directly; they always should be accessed via macros; base16_value() base16_digit()
9 //
10 
11 const int base10_lookup[] = {
12  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
13  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
14  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
15  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
16  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
17  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
18  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
19  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
20  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
21  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
22  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
24  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
25  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
26  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
27  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
28 };
29 
30 const int base16_lookup[] = {
31  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
32  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
33  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
34  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
35  -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
36  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
37  -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
38  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
39  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
44  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
45  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
46  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
47 };
48 
49 const int base26_lookup[] = {
50  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
51  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
52  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
53  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
54  -1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
55  16,17,18,19,20,21,22,23,24,25,26,-1,-1,-1,-1,-1,
56  -1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
57  16,17,18,19,20,21,22,23,24,25,26,-1,-1,-1,-1,-1,
58  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
59  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
60  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
61  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
62  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
63  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
64  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
65  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
66 };
67 
68 const int base36_lookup[] = {
69  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
70  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
71  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
72  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
73  -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
74  25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
75  -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
76  25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
77  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
78  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
79  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
80  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
81  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
82  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
83  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
84  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
85 };
86 
87 /* common buffer for quick conversions (unsafe) */
88 
90 
91 /* integer from string; return a pointer to character next to the last digit */
92 
93 #define string_scan_sign(s, c, sign) _scan_sign(c, sign, *++s)
94 #define string_scan_integer(s, c, number) _scan_integer(c, number, *++s)
95 #define string_scan_radix(s, c, number, radix) _scan_radix(c, number, radix, *++s)
96 #define string_read_integer(s, c, number) _read_integer(c, number, *++s)
97 #define string_read_radix(s, c, number, radix) _read_radix(c, number, radix, *++s)
98 
99 const char * string_to_int32 (const char *s, int32_t *number)
100 {
101  int sign, c = *s;
104  if (sign) *number = -*number;
105  return s;
106 }
107 
108 const char * string_to_slong (const char *s, long *number)
109 {
110  int sign, c = *s;
113  if (sign) *number = -*number;
114  return s;
115 }
116 
117 const char * string_to_int64 (const char *s, int64_t *number)
118 {
119  int sign, c = *s;
122  if (sign) *number = -*number;
123  return s;
124 }
125 
126 const char * string_to_uint32 (const char *s, uint32_t *number)
127 {
128  int c = *s;
130  return s;
131 }
132 
133 const char * string_to_ulong (const char *s, unsigned long *number)
134 {
135  int c = *s;
137  return s;
138 }
139 
140 const char * string_to_usize (const char *s, size_t *number)
141 {
142  int c = *s;
144  return s;
145 }
146 
147 const char * string_to_uint64 (const char *s, uint64_t *number)
148 {
149  int c = *s;
151  return s;
152 }
153 
154 const char * radix_to_int32 (const char *s, int32_t *number, int radix)
155 {
156  int sign, c = *s;
159  if (sign) *number = -*number;
160  return s;
161 }
162 
163 const char * radix_to_slong (const char *s, long *number, int radix)
164 {
165  int sign, c = *s;
168  if (sign) *number = -*number;
169  return s;
170 }
171 
172 const char * radix_to_int64 (const char *s, int64_t *number, int radix)
173 {
174  int sign, c = *s;
177  if (sign) *number = -*number;
178  return s;
179 }
180 
181 const char * radix_to_uint32 (const char *s, uint32_t *number, int radix)
182 {
183  int c = *s;
185  return s;
186 }
187 
188 const char * radix_to_ulong (const char *s, unsigned long *number, int radix)
189 {
190  int c = *s;
192  return s;
193 }
194 
195 const char * radix_to_usize (const char *s, size_t *number, int radix)
196 {
197  int c = *s;
199  return s;
200 }
201 
202 const char * radix_to_uint64 (const char *s, uint64_t *number, int radix)
203 {
204  int c = *s;
206  return s;
207 }
208 
209 /* roman to uint16_t */
210 
211 #define roman1000(c) (c == 'M' || c == 'm')
212 #define roman500(c) (c == 'D' || c == 'd')
213 #define roman100(c) (c == 'C' || c == 'c')
214 #define roman50(c) (c == 'L' || c == 'l')
215 #define roman10(c) (c == 'X' || c == 'x')
216 #define roman5(c) (c == 'V' || c == 'v')
217 #define roman1(c) (c == 'I' || c == 'i')
218 
219 #define roman100s(p) (roman100(*p) ? (100 + ((++p, roman100(*p)) ? (100 + ((++p, roman100(*p)) ? (++p, 100) : 0)) : 0)) : 0)
220 #define roman10s(p) (roman10(*p) ? (10 + ((++p, roman10(*p)) ? (10 + ((++p, roman10(*p)) ? (++p, 10) : 0)) : 0)) : 0)
221 #define roman1s(p) (roman1(*p) ? (1 + ((++p, roman1(*p)) ? (1 + ((++p, roman1(*p)) ? (++p, 1) : 0)) : 0)) : 0)
222 
223 const char * roman_to_uint16 (const char *s, uint16_t *number)
224 {
225  const char *p;
226  /* M */
227  for (*number = 0, p = s; roman1000(*p); *number += 1000, ++p);
228  /* D C */
229  if (roman500(*p))
230  {
231  ++p;
232  *number += 500 + roman100s(p);
233  }
234  else if (roman100(*p))
235  {
236  ++p;
237  if (roman1000(*p))
238  {
239  ++p;
240  *number += 900;
241  }
242  else if (roman500(*p))
243  {
244  ++p;
245  *number += 400;
246  }
247  else
248  *number += 100 + roman100s(p);
249  }
250  /* L X */
251  if (roman50(*p))
252  {
253  ++p;
254  *number += 50 + roman10s(p);
255  }
256  else if (roman10(*p))
257  {
258  ++p;
259  if (roman100(*p))
260  {
261  ++p;
262  *number += 90;
263  }
264  else if (roman50(*p))
265  {
266  ++p;
267  *number += 40;
268  }
269  else
270  *number += 10 + roman10s(p);
271  }
272  /* V I */
273  if (roman5(*p))
274  {
275  ++p;
276  *number += 5 + roman1s(p);
277  }
278  else if (roman1(*p))
279  {
280  ++p;
281  if (roman10(*p))
282  {
283  ++p;
284  *number += 9;
285  }
286  else if (roman5(*p))
287  {
288  ++p;
289  *number += 4;
290  }
291  else
292  *number += 1 + roman1s(p);
293  }
294  return p;
295 }
296 
297 /* integer to string; return a pointer to null-terminated static const string */
298 
299 #define end_of_integer_buffer(integer_buffer) (integer_buffer + MAX_INTEGER_DIGITS - 1)
300 
301 #define number_printrev_signed(p, number, quotient) \
302  do { \
303  quotient = number; number /= 10; \
304  *--p = base10_palindrome[9 + (quotient - number*10)]; \
305  } while (number); \
306  if (quotient < 0) *--p = '-'
307 
308 #define number_printrev_unsigned(p, number, quotient) \
309  do { \
310  quotient = number; number /= 10; \
311  *--p = (char)(quotient - integer_multiplied10(number)) + '0'; \
312  } while (number)
313 
314 #define SINTTYPE_AS_STRING(inttype, number, ibuf, psize) \
315  char *p, *e; \
316  inttype quotient; \
317  e = p = end_of_integer_buffer(ibuf); *p = '\0'; \
318  number_printrev_signed(p, number, quotient); \
319  *psize = (size_t)(e - p)
320 
321 #define UINTTYPE_AS_STRING(inttype, number, ibuf, psize) \
322  char *p, *e; \
323  inttype quotient; \
324  e = p = end_of_integer_buffer(ibuf); *p = '\0'; \
325  number_printrev_unsigned(p, number, quotient); \
326  *psize = (size_t)(e - p)
327 
328 char * int32_as_string (int32_t number, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
329 {
331  return p;
332 }
333 
334 char * slong_as_string (long number, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
335 {
336  SINTTYPE_AS_STRING(long, number, ibuf, psize);
337  return p;
338 }
339 
340 char * int64_as_string (int64_t number, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
341 {
343  return p;
344 }
345 
347 {
349  return p;
350 }
351 
352 char * ulong_as_string (unsigned long number, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
353 {
354  UINTTYPE_AS_STRING(unsigned long, number, ibuf, psize);
355  return p;
356 }
357 
358 char * usize_as_string (size_t number, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
359 {
360  UINTTYPE_AS_STRING(size_t, number, ibuf, psize);
361  return p;
362 }
363 
365 {
367  return p;
368 }
369 
370 /* radix variant */
371 
372 #define number_printrev_signed_radix_uc(p, number, radix, quotient) \
373  do { \
374  quotient = number; number /= radix; \
375  *--p = base36_uc_palindrome[MAX_RADIX - 1 + (quotient - number*radix)]; \
376  } while (number)
377 
378 #define number_printrev_signed_radix_lc(p, number, radix, quotient) \
379  do { \
380  quotient = number; number /= radix; \
381  *--p = base36_lc_palindrome[MAX_RADIX - 1 + (quotient - number*radix)]; \
382  } while (number)
383 
384 #define number_printrev_signed_radix(p, number, radix, quotient, uc) \
385  do { \
386  if (uc) { number_printrev_signed_radix_uc(p, number, radix, quotient); } \
387  else { number_printrev_signed_radix_lc(p, number, radix, quotient); } \
388  if (quotient < 0) *--p = '-'; \
389  } while (0)
390 
391 #define number_printrev_unsigned_radix_uc(p, number, radix, quotient) \
392  do { \
393  quotient = number; number /= radix; \
394  *--p = base36_uc_alphabet[quotient % radix]; \
395  } while (number)
396 
397 #define number_printrev_unsigned_radix_lc(p, number, radix, quotient) \
398  do { \
399  quotient = number; number /= radix; \
400  *--p = base36_lc_alphabet[quotient % radix]; \
401  } while (number)
402 
403 #define number_printrev_unsigned_radix(p, number, radix, quotient, uc) \
404  do { \
405  if (uc) { number_printrev_unsigned_radix_uc(p, number, radix, quotient); } \
406  else { number_printrev_unsigned_radix_lc(p, number, radix, quotient); } \
407  } while (0)
408 
409 #define SINTTYPE_AS_RADIX(inttype, number, radix, uc, ibuf, psize) \
410  char *p, *e; \
411  inttype quotient; \
412  e = p = end_of_integer_buffer(ibuf); *p = '\0'; \
413  number_printrev_signed_radix(p, number, radix, quotient, uc); \
414  *psize = (size_t)(e - p)
415 
416 #define UINTTYPE_AS_RADIX(inttype, number, radix, uc, ibuf, psize) \
417  char *p, *e; \
418  inttype quotient; \
419  e = p = end_of_integer_buffer(ibuf); *p = '\0'; \
420  number_printrev_unsigned_radix(p, number, radix, quotient, uc); \
421  *psize = (size_t)(e - p)
422 
423 char * int32_as_radix (int32_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
424 {
425  SINTTYPE_AS_RADIX(int32_t, number, radix, uc, ibuf, psize);
426  return p;
427 }
428 
429 char * slong_as_radix (long number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
430 {
431  SINTTYPE_AS_RADIX(long, number, radix, uc, ibuf, psize);
432  return p;
433 }
434 
435 /*
436 char * ssize_as_radix (ssize_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
437 {
438  SINTTYPE_AS_RADIX(ssize_t, number, radix, uc, ibuf, psize);
439  return p;
440 }
441 */
442 
443 char * int64_as_radix (int64_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
444 {
445  SINTTYPE_AS_RADIX(int64_t, number, radix, uc, ibuf, psize);
446  return p;
447 }
448 
449 char * uint32_as_radix (uint32_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
450 {
451  UINTTYPE_AS_RADIX(uint32_t, number, radix, uc, ibuf, psize);
452  return p;
453 }
454 
455 char * ulong_as_radix (unsigned long number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
456 {
457  UINTTYPE_AS_RADIX(unsigned long, number, radix, uc, ibuf, psize);
458  return p;
459 }
460 
461 char * usize_as_radix (size_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
462 {
463  UINTTYPE_AS_RADIX(size_t, number, radix, uc, ibuf, psize);
464  return p;
465 }
466 
467 char * uint64_as_radix (uint64_t number, int radix, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
468 {
469  UINTTYPE_AS_RADIX(uint64_t, number, radix, uc, ibuf, psize);
470  return p;
471 }
472 
473 /* aaa, aab, aac, ...; unsigned only. 0 gives empty string */
474 
475 #define string_scan_alpha(s, c, number, radix) \
476  for (number = 0, c = *s; (c = base26_value(c)) > 0; number = number * radix + c, c = *++s)
477 
478 const char * alpha_to_uint32 (const char *s, uint32_t *number)
479 {
480  int c;
481  string_scan_alpha(s, c, *number, 26);
482  return s;
483 }
484 
485 const char * alpha_to_ulong (const char *s, unsigned long *number)
486 {
487  int c;
488  string_scan_alpha(s, c, *number, 26);
489  return s;
490 }
491 
492 const char * alpha_to_usize (const char *s, size_t *number)
493 {
494  int c;
495  string_scan_alpha(s, c, *number, 26);
496  return s;
497 }
498 
499 const char * alpha_to_uint64 (const char *s, uint64_t *number)
500 {
501  int c;
502  string_scan_alpha(s, c, *number, 26);
503  return s;
504 }
505 
506 #define number_printrev_unsigned_alpha_uc(p, number, radix, quotient) \
507  while (number > 0) { \
508  quotient = --number; number /= radix; \
509  *--p = base26_uc_alphabet[quotient % radix]; \
510  }
511 
512 #define number_printrev_unsigned_alpha_lc(p, number, radix, quotient) \
513  while (number > 0) { \
514  quotient = --number; number /= radix; \
515  *--p = base26_lc_alphabet[quotient % radix]; \
516  }
517 
518 #define UINTTYPE_AS_ALPHA(inttype, number, uc, ibuf, psize) \
519  char *p, *e; \
520  inttype quotient; \
521  e = p = end_of_integer_buffer(ibuf); *p = '\0'; \
522  if (uc) { number_printrev_unsigned_alpha_uc(p, number, 26, quotient); } \
523  else { number_printrev_unsigned_alpha_lc(p, number, 26, quotient); } \
524  *psize = (size_t)(e - p)
525 
526 char * uint32_as_alpha (uint32_t number, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
527 {
528  UINTTYPE_AS_ALPHA(uint32_t, number, uc, ibuf, psize);
529  return p;
530 }
531 
532 char * ulong_as_alpha (unsigned long number, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
533 {
534  UINTTYPE_AS_ALPHA(unsigned long, number, uc, ibuf, psize);
535  return p;
536 }
537 
538 char * usize_as_alpha (size_t number, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
539 {
540  UINTTYPE_AS_ALPHA(size_t, number, uc, ibuf, psize);
541  return p;
542 }
543 
544 char * uint64_as_alpha (uint64_t number, int uc, char ibuf[MAX_INTEGER_DIGITS], size_t *psize)
545 {
546  UINTTYPE_AS_ALPHA(uint64_t, number, uc, ibuf, psize);
547  return p;
548 }
549 
550 /* a variant of alphabetic, a, b, c, ..., z, aa, bb, cc, ..., zz (eg. pdf page labelling)
551  watch out: unsafe for large numbers; for buffer size N we can handle max. N * 26. */
552 
553 #define string_scan_alphan(s, c, number, radix) \
554  do { \
555  number = 0; \
556  if ((c = (uint16_t)base26_value(*s)) > 0) { \
557  number = c; \
558  while (c == (uint16_t)base26_value(*++s)) number += radix; \
559  } \
560  } while (0)
561 
562 const char * alphan_to_uint16 (const char *s, uint16_t *number)
563 {
564  uint16_t c;
565  string_scan_alphan(s, c, *number, 26);
566  return s;
567 }
568 
569 #define number_print_alphan_uc(p, e, c, number, radix) \
570  for (c = (--number) % radix, number -= c; ; number -= radix) { \
571  *p++ = base26_uc_alphabet[c]; \
572  if (number == 0 || p >= e) break; \
573  }
574 
575 #define number_print_alphan_lc(p, e, c, number, radix) \
576  for (c = (--number) % radix, number -= c; ; number -= radix) { \
577  *p++ = base26_lc_alphabet[c]; \
578  if (number == 0 || p >= e) break; \
579  }
580 
581 #define UINTTYPE_AS_ALPHAN(inttype, number, uc, ibuf, size, psize) \
582  char *p, *e; \
583  uint8_t c; \
584  p = ibuf; \
585  e = p + size; \
586  if (number > 0) { \
587  if (uc) { number_print_alphan_uc(p, e, c, number, 26); } \
588  else { number_print_alphan_lc(p, e, c, number, 26); } \
589  } \
590  *p = '\0'; \
591  *psize = (size_t)(p - ibuf)
592 
593 char * uint16_as_alphan (uint16_t number, int uc, char ibuf[], size_t size, size_t *psize)
594 {
595  UINTTYPE_AS_ALPHAN(uint16_t, number, uc, ibuf, size, psize);
596  return ibuf;
597 }
598 
599 /* roman numeral */
600 
601 /* large roman numerals? http://mathforum.org/library/drmath/view/57569.html */
602 
603 #define base_roman_uc_alphabet "MDCLXVI"
604 #define base_roman_lc_alphabet "mdclxvi"
605 
606 char * uint16_as_roman (uint16_t number, int uc, char ibuf[MAX_ROMAN_DIGITS], size_t *psize)
607 {
608  static const uint32_t base_roman_values[] = { 1000, 500, 100, 50, 10, 5, 1 };
609  const char *alphabet;
610  char *p;
611  uint32_t k, j, v, u, n;
612 
613  n = (uint32_t)number; // uint16_t used to limit leding 'M'
615  for (p = ibuf, j = 0, v = base_roman_values[0]; n > 0; )
616  {
617  if (n >= v)
618  {
619  *p++ = alphabet[j];
620  n -= v;
621  continue;
622  }
623  if (j & 1)
624  k = j + 1;
625  else
626  k = j + 2;
627  u = base_roman_values[k];
628  if (n + u >= v)
629  {
630  *p++ = alphabet[k];
631  n += u;
632  }
633  else
634  v = base_roman_values[++j];
635  }
636  *p = '\0';
637  *psize = (size_t)(p - ibuf);
638  return ibuf;
639 }
640 
641 /* IEEE-754 */
642 
643 #define BINARY_MODF 1
644 
645 #define NOT_A_NUMBER_STRING "NaN"
646 #define INFINITY_STRING "INF"
647 #define SIGNED_INFINITY 1
648 #define SIGNED_ZERO 0
649 #define SIGNED_NOT_A_NUMBER 0
650 #define RADIX_CHAR '.'
651 
652 /* double/float to decimal */
653 
654 typedef struct ieee_double {
655  union {
656  double number;
657  uint64_t bits;
658  };
660  int exponent, sign;
662 
663 typedef struct ieee_float {
664  union {
665  float number;
666  uint32_t bits;
667  };
669  int exponent, sign;
671 
672 #define IEEE_DOUBLE_BIAS 1023
673 #define IEEE_DOUBLE_MIN_EXPONENT -1023
674 #define IEEE_DOUBLE_MAX_EXPONENT (0x7ff - IEEE_DOUBLE_BIAS)
675 
676 #define IEEE_FLOAT_BIAS 127
677 #define IEEE_FLOAT_MIN_EXPONENT -127
678 #define IEEE_FLOAT_MAX_EXPONENT (0xff - IEEE_FLOAT_BIAS)
679 
680 #define ieee_double_fraction(i) (i & 0x000fffffffffffffull)
681 #define ieee_double_exponent(i) ((0x7ff & (i >> 52)) - IEEE_DOUBLE_BIAS)
682 #define ieee_double_init(ieee_number, number) \
683  ieee_number.number = number, \
684  ieee_number.fraction = ieee_double_fraction(ieee_number.bits), \
685  ieee_number.exponent = ieee_double_exponent(ieee_number.bits)
686 
687 #define ieee_float_fraction(i) (i & 0x007fffff)
688 #define ieee_float_exponent(i) ((0xff & (i >> 23)) - IEEE_FLOAT_BIAS)
689 #define ieee_float_init(ieee_number, number) \
690  ieee_number.number = number, \
691  ieee_number.fraction = ieee_float_fraction(ieee_number.bits), \
692  ieee_number.exponent = ieee_float_exponent(ieee_number.bits)
693 
694 /* special cases */
695 
696 #define ieee_double_is_zero(ieee_number) (ieee_number.number == 0) // || ieee_double_too_small(ieee_number) ?
697 #define ieee_double_too_small(ieee_number) (ieee_number.exponent == 0 && ieee_number.fraction != 0) // denormalized, implicit fracion bit not set
698 
699 #define ieee_float_is_zero(ieee_number) (ieee_number.number == 0) // || ieee_float_too_small(ieee_number) ?
700 #define ieee_float_too_small(ieee_number) (ieee_number.exponent == 0 && ieee_number.fraction != 0)
701 
702 #define ieee_double_zero_string(ieee_number) (SIGNED_ZERO && ieee_number.sign ? "-0" : "0")
703 #define ieee_double_infinity_string(ieee_number) (SIGNED_INFINITY && ieee_number.sign ? "-" INFINITY_STRING : INFINITY_STRING)
704 
705 #define ieee_float_zero_string ieee_double_zero_string
706 #define ieee_float_infinity_string ieee_double_infinity_string
707 
708 #define ieee_double_special_case(ieee_number) (ieee_number.exponent == IEEE_DOUBLE_MAX_EXPONENT)
709 #define ieee_double_special_string(ieee_number) (ieee_number.fraction ? NOT_A_NUMBER_STRING : ieee_double_infinity_string(ieee_number))
710 
711 #define ieee_float_special_case(ieee_number) (ieee_number.exponent == IEEE_FLOAT_MAX_EXPONENT)
712 #define ieee_float_special_string(ieee_number) (ieee_number.fraction ? NOT_A_NUMBER_STRING : ieee_float_infinity_string(ieee_number))
713 
714 #if 0
715 
716 const double double_binary_power10[] =
717 {
718  1.0e1, 1.0e2, 1.0e4, 1.0e8, 1.0e16, 1.0e32, 1.0e64, 1.0e128, 1.0e256
719 };
720 
721 const float float_binary_power10[] =
722 {
723  1.0e1, 1.0e2, 1.0e4, 1.0e8, 1.0e16, 1.0e32
724 };
725 
726 const double double_binary_negpower10[] =
727 {
728  1.0e-1, 1.0e-2, 1.0e-4, 1.0e-8, 1.0e-16, 1.0e-32
729 };
730 
731 const float float_binary_negpower10[] =
732 {
733  1.0e-1, 1.0e-2, 1.0e-4, 1.0e-8, 1.0e-16, 1.0e-32
734 };
735 
736 #else
737 
738 const double double_decimal_power10[] = {
739  1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9,
740  1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19,
741  1.0e20, 1.0e21, 1.0e22, 1.0e23, 1.0e24, 1.0e25, 1.0e26, 1.0e27, 1.0e28, 1.0e29,
742  1.0e30, 1.0e31, 1.0e32, 1.0e33, 1.0e34, 1.0e35, 1.0e36, 1.0e37, 1.0e38, 1.0e39,
743  1.0e40, 1.0e41, 1.0e42, 1.0e43, 1.0e44, 1.0e45, 1.0e46, 1.0e47, 1.0e48, 1.0e49,
744  1.0e50, 1.0e51, 1.0e52, 1.0e53, 1.0e54, 1.0e55, 1.0e56, 1.0e57, 1.0e58, 1.0e59,
745  1.0e60, 1.0e61, 1.0e62, 1.0e63, 1.0e64, 1.0e65, 1.0e66, 1.0e67, 1.0e68, 1.0e69,
746  1.0e70, 1.0e71, 1.0e72, 1.0e73, 1.0e74, 1.0e75, 1.0e76, 1.0e77, 1.0e78, 1.0e79,
747  1.0e80, 1.0e81, 1.0e82, 1.0e83, 1.0e84, 1.0e85, 1.0e86, 1.0e87, 1.0e88, 1.0e89,
748  1.0e90, 1.0e91, 1.0e92, 1.0e93, 1.0e94, 1.0e95, 1.0e96, 1.0e97, 1.0e98, 1.0e99,
749  1.0e100, 1.0e101, 1.0e102, 1.0e103, 1.0e104, 1.0e105, 1.0e106, 1.0e107, 1.0e108, 1.0e109,
750  1.0e110, 1.0e111, 1.0e112, 1.0e113, 1.0e114, 1.0e115, 1.0e116, 1.0e117, 1.0e118, 1.0e119,
751  1.0e120, 1.0e121, 1.0e122, 1.0e123, 1.0e124, 1.0e125, 1.0e126, 1.0e127, 1.0e128, 1.0e129,
752  1.0e130, 1.0e131, 1.0e132, 1.0e133, 1.0e134, 1.0e135, 1.0e136, 1.0e137, 1.0e138, 1.0e139,
753  1.0e140, 1.0e141, 1.0e142, 1.0e143, 1.0e144, 1.0e145, 1.0e146, 1.0e147, 1.0e148, 1.0e149,
754  1.0e150, 1.0e151, 1.0e152, 1.0e153, 1.0e154, 1.0e155, 1.0e156, 1.0e157, 1.0e158, 1.0e159,
755  1.0e160, 1.0e161, 1.0e162, 1.0e163, 1.0e164, 1.0e165, 1.0e166, 1.0e167, 1.0e168, 1.0e169,
756  1.0e170, 1.0e171, 1.0e172, 1.0e173, 1.0e174, 1.0e175, 1.0e176, 1.0e177, 1.0e178, 1.0e179,
757  1.0e180, 1.0e181, 1.0e182, 1.0e183, 1.0e184, 1.0e185, 1.0e186, 1.0e187, 1.0e188, 1.0e189,
758  1.0e190, 1.0e191, 1.0e192, 1.0e193, 1.0e194, 1.0e195, 1.0e196, 1.0e197, 1.0e198, 1.0e199,
759  1.0e200, 1.0e201, 1.0e202, 1.0e203, 1.0e204, 1.0e205, 1.0e206, 1.0e207, 1.0e208, 1.0e209,
760  1.0e210, 1.0e211, 1.0e212, 1.0e213, 1.0e214, 1.0e215, 1.0e216, 1.0e217, 1.0e218, 1.0e219,
761  1.0e220, 1.0e221, 1.0e222, 1.0e223, 1.0e224, 1.0e225, 1.0e226, 1.0e227, 1.0e228, 1.0e229,
762  1.0e230, 1.0e231, 1.0e232, 1.0e233, 1.0e234, 1.0e235, 1.0e236, 1.0e237, 1.0e238, 1.0e239,
763  1.0e240, 1.0e241, 1.0e242, 1.0e243, 1.0e244, 1.0e245, 1.0e246, 1.0e247, 1.0e248, 1.0e249,
764  1.0e250, 1.0e251, 1.0e252, 1.0e253, 1.0e254, 1.0e255, 1.0e256, 1.0e257, 1.0e258, 1.0e259,
765  1.0e260, 1.0e261, 1.0e262, 1.0e263, 1.0e264, 1.0e265, 1.0e266, 1.0e267, 1.0e268, 1.0e269,
766  1.0e270, 1.0e271, 1.0e272, 1.0e273, 1.0e274, 1.0e275, 1.0e276, 1.0e277, 1.0e278, 1.0e279,
767  1.0e280, 1.0e281, 1.0e282, 1.0e283, 1.0e284, 1.0e285, 1.0e286, 1.0e287, 1.0e288, 1.0e289,
768  1.0e290, 1.0e291, 1.0e292, 1.0e293, 1.0e294, 1.0e295, 1.0e296, 1.0e297, 1.0e298, 1.0e299,
769  1.0e300, 1.0e301, 1.0e302, 1.0e303, 1.0e304, 1.0e305, 1.0e306, 1.0e307, 1.0e308
770 };
771 
772 const float float_decimal_power10[] = {
773  1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f, 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f,
774  1.0e10f, 1.0e11f, 1.0e12f, 1.0e13f, 1.0e14f, 1.0e15f, 1.0e16f, 1.0e17f, 1.0e18f, 1.0e19f,
775  1.0e20f, 1.0e21f, 1.0e22f, 1.0e23f, 1.0e24f, 1.0e25f, 1.0e26f, 1.0e27f, 1.0e28f, 1.0e29f,
776  1.0e30f, 1.0e31f, 1.0e32f, 1.0e33f, 1.0e34f, 1.0e35f, 1.0e36f, 1.0e37f, 1.0e38f
777 };
778 
779 const double double_decimal_negpower10[] = {
780  1.0e0, 1.0e-1, 1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6, 1.0e-7, 1.0e-8, 1.0e-9,
781  1.0e-10, 1.0e-11, 1.0e-12, 1.0e-13, 1.0e-14, 1.0e-15, 1.0e-16, 1.0e-17, 1.0e-18, 1.0e-19,
782  1.0e-20, 1.0e-21, 1.0e-22, 1.0e-23, 1.0e-24, 1.0e-25, 1.0e-26, 1.0e-27, 1.0e-28, 1.0e-29,
783  1.0e-30, 1.0e-31, 1.0e-32, 1.0e-33, 1.0e-34, 1.0e-35, 1.0e-36, 1.0e-37, 1.0e-38, 1.0e-39,
784  1.0e-40, 1.0e-41, 1.0e-42, 1.0e-43, 1.0e-44, 1.0e-45, 1.0e-46, 1.0e-47, 1.0e-48, 1.0e-49,
785  1.0e-50, 1.0e-51, 1.0e-52, 1.0e-53, 1.0e-54, 1.0e-55, 1.0e-56, 1.0e-57, 1.0e-58, 1.0e-59,
786  1.0e-60, 1.0e-61, 1.0e-62, 1.0e-63, 1.0e-64, 1.0e-65, 1.0e-66, 1.0e-67, 1.0e-68, 1.0e-69,
787  1.0e-70, 1.0e-71, 1.0e-72, 1.0e-73, 1.0e-74, 1.0e-75, 1.0e-76, 1.0e-77, 1.0e-78, 1.0e-79,
788  1.0e-80, 1.0e-81, 1.0e-82, 1.0e-83, 1.0e-84, 1.0e-85, 1.0e-86, 1.0e-87, 1.0e-88, 1.0e-89,
789  1.0e-90, 1.0e-91, 1.0e-92, 1.0e-93, 1.0e-94, 1.0e-95, 1.0e-96, 1.0e-97, 1.0e-98, 1.0e-99,
790  1.0e-100, 1.0e-101, 1.0e-102, 1.0e-103, 1.0e-104, 1.0e-105, 1.0e-106, 1.0e-107, 1.0e-108, 1.0e-109,
791  1.0e-110, 1.0e-111, 1.0e-112, 1.0e-113, 1.0e-114, 1.0e-115, 1.0e-116, 1.0e-117, 1.0e-118, 1.0e-119,
792  1.0e-120, 1.0e-121, 1.0e-122, 1.0e-123, 1.0e-124, 1.0e-125, 1.0e-126, 1.0e-127, 1.0e-128, 1.0e-129,
793  1.0e-130, 1.0e-131, 1.0e-132, 1.0e-133, 1.0e-134, 1.0e-135, 1.0e-136, 1.0e-137, 1.0e-138, 1.0e-139,
794  1.0e-140, 1.0e-141, 1.0e-142, 1.0e-143, 1.0e-144, 1.0e-145, 1.0e-146, 1.0e-147, 1.0e-148, 1.0e-149,
795  1.0e-150, 1.0e-151, 1.0e-152, 1.0e-153, 1.0e-154, 1.0e-155, 1.0e-156, 1.0e-157, 1.0e-158, 1.0e-159,
796  1.0e-160, 1.0e-161, 1.0e-162, 1.0e-163, 1.0e-164, 1.0e-165, 1.0e-166, 1.0e-167, 1.0e-168, 1.0e-169,
797  1.0e-170, 1.0e-171, 1.0e-172, 1.0e-173, 1.0e-174, 1.0e-175, 1.0e-176, 1.0e-177, 1.0e-178, 1.0e-179,
798  1.0e-180, 1.0e-181, 1.0e-182, 1.0e-183, 1.0e-184, 1.0e-185, 1.0e-186, 1.0e-187, 1.0e-188, 1.0e-189,
799  1.0e-190, 1.0e-191, 1.0e-192, 1.0e-193, 1.0e-194, 1.0e-195, 1.0e-196, 1.0e-197, 1.0e-198, 1.0e-199,
800  1.0e-200, 1.0e-201, 1.0e-202, 1.0e-203, 1.0e-204, 1.0e-205, 1.0e-206, 1.0e-207, 1.0e-208, 1.0e-209,
801  1.0e-210, 1.0e-211, 1.0e-212, 1.0e-213, 1.0e-214, 1.0e-215, 1.0e-216, 1.0e-217, 1.0e-218, 1.0e-219,
802  1.0e-220, 1.0e-221, 1.0e-222, 1.0e-223, 1.0e-224, 1.0e-225, 1.0e-226, 1.0e-227, 1.0e-228, 1.0e-229,
803  1.0e-230, 1.0e-231, 1.0e-232, 1.0e-233, 1.0e-234, 1.0e-235, 1.0e-236, 1.0e-237, 1.0e-238, 1.0e-239,
804  1.0e-240, 1.0e-241, 1.0e-242, 1.0e-243, 1.0e-244, 1.0e-245, 1.0e-246, 1.0e-247, 1.0e-248, 1.0e-249,
805  1.0e-250, 1.0e-251, 1.0e-252, 1.0e-253, 1.0e-254, 1.0e-255, 1.0e-256, 1.0e-257, 1.0e-258, 1.0e-259,
806  1.0e-260, 1.0e-261, 1.0e-262, 1.0e-263, 1.0e-264, 1.0e-265, 1.0e-266, 1.0e-267, 1.0e-268, 1.0e-269,
807  1.0e-270, 1.0e-271, 1.0e-272, 1.0e-273, 1.0e-274, 1.0e-275, 1.0e-276, 1.0e-277, 1.0e-278, 1.0e-279,
808  1.0e-280, 1.0e-281, 1.0e-282, 1.0e-283, 1.0e-284, 1.0e-285, 1.0e-286, 1.0e-287, 1.0e-288, 1.0e-289,
809  1.0e-290, 1.0e-291, 1.0e-292, 1.0e-293, 1.0e-294, 1.0e-295, 1.0e-296, 1.0e-297, 1.0e-298, 1.0e-299,
810  1.0e-300, 1.0e-301, 1.0e-302, 1.0e-303, 1.0e-304, 1.0e-305, 1.0e-306, 1.0e-307, 1.0e-308
811 };
812 
813 const float float_decimal_negpower10[] = {
814  1.0e0f, 1.0e-1f, 1.0e-2f, 1.0e-3f, 1.0e-4f, 1.0e-5f, 1.0e-6f, 1.0e-7f, 1.0e-8f, 1.0e-9f,
815  1.0e-10f, 1.0e-11f, 1.0e-12f, 1.0e-13f, 1.0e-14f, 1.0e-15f, 1.0e-16f, 1.0e-17f, 1.0e-18f, 1.0e-19f,
816  1.0e-20f, 1.0e-21f, 1.0e-22f, 1.0e-23f, 1.0e-24f, 1.0e-25f, 1.0e-26f, 1.0e-27f, 1.0e-28f, 1.0e-29f,
817  1.0e-30f, 1.0e-31f, 1.0e-32f, 1.0e-33f, 1.0e-34f, 1.0e-35f, 1.0e-36f, 1.0e-37f, 1.0e-38f
818 };
819 
820 #endif
821 
822 /* scale number by floor(log10(number)) + 1 so that the result is in range [0.1, 1) */
823 
824 #define ieee_double_exponent10(ieee_number) ((int)floor(log10(ieee_number.number)) + 1)
825 #define ieee_float_exponent10(ieee_number) ((int)floorf(log10f(ieee_number.number)) + 1) // floorf, log10f ?
826 
827 #define ieee_double_exp10(ieee_number, exponent10) \
828  exponent10 = ieee_double_exponent10(ieee_number); \
829  if (exponent10 > 0) { \
830  double_negative_exp10(ieee_number.number, -exponent10); \
831  ieee_number.fraction = ieee_double_fraction(ieee_number.bits); \
832  ieee_number.exponent = ieee_double_exponent(ieee_number.bits); \
833  } else if (exponent10 < 0) { \
834  double_positive_exp10(ieee_number.number, -exponent10); \
835  ieee_number.fraction = ieee_double_fraction(ieee_number.bits); \
836  ieee_number.exponent = ieee_double_exponent(ieee_number.bits); \
837  }
838 
839 #define ieee_float_exp10(ieee_number, exponent10) \
840  exponent10 = ieee_float_exponent10(ieee_number); \
841  if (exponent10 > 0) { \
842  float_negative_exp10(ieee_number.number, -exponent10); \
843  ieee_number.fraction = ieee_float_fraction(ieee_number.bits); \
844  ieee_number.exponent = ieee_float_exponent(ieee_number.bits); \
845  } else if (exponent10 < 0) { \
846  float_positive_exp10(ieee_number.number, -exponent10); \
847  ieee_number.fraction = ieee_float_fraction(ieee_number.bits); \
848  ieee_number.exponent = ieee_float_exponent(ieee_number.bits); \
849  }
850 
851 #if BINARY_MODF
852 
853 /* unhide implicit bit 53, produce 56-bit denormalised fraction (binary exponent already in range [-4, -1]) */
854 
855 #define ieee_double_denormalize(ieee_number) \
856  (ieee_number.exponent == IEEE_DOUBLE_MIN_EXPONENT ? (++ieee_number.exponent, 0) : (ieee_number.fraction |= (1ull<<52))), \
857  ieee_number.fraction <<= (ieee_number.exponent + 4)
858 
859 /* unhide implicit bit 24, produce 27-bit denormalized fraction (binary exponent already in range [-4, -1]) */
860 
861 #define ieee_float_denormalize(ieee_number) \
862  (ieee_number.exponent == IEEE_FLOAT_MIN_EXPONENT ? (++ieee_number.exponent, 0) : (ieee_number.fraction |= (1<<23))), \
863  ieee_number.fraction <<= (ieee_number.exponent + 4)
864 
865 /* turn off significant bits over 56 (integer part), multiply by 10, return new integer part (subsequent decimal digit) */
866 
867 #define ieee_double_binary_fraction(ieee_number) \
868  (ieee_number.fraction &= ((1ull<<56) - 1), \
869  ieee_number.fraction = (ieee_number.fraction << 1) + (ieee_number.fraction << 3), \
870  ieee_number.fraction >> 56)
871 
872 /* turn off significant bits over 27 (integer part), multiply by 10, return the integer part (subsequent decimal digit) */
873 
874 #define ieee_float_binary_fraction(ieee_number) \
875  (ieee_number.fraction &= ((1<<27) - 1), \
876  ieee_number.fraction = (ieee_number.fraction << 1) + (ieee_number.fraction << 3), \
877  ieee_number.fraction >> 27)
878 
879 #define ieee_double_decimal(ieee_number, exponent10, digits, p) \
880  ieee_number_decimal(ieee_double_binary_fraction, ieee_number, exponent10, digits, p)
881 #define ieee_float_decimal(ieee_number, exponent10, digits, p) \
882  ieee_number_decimal(ieee_float_binary_fraction, ieee_number, exponent10, digits, p)
883 
884 #else
885 
886 /* generic method */
887 
888 #define ieee_double_decimal_fraction(ieee_number, i) (ieee_number.number = modf(10*ieee_number.number, &i), i)
889 #define ieee_float_decimal_fraction(ieee_number, i) (ieee_number.number = (float)modf(10*ieee_number.number, &i), i) // ???
890 
891 #define ieee_double_decimal(ieee_number, exponent10, digits, p) \
892  ieee_number_decimal(ieee_double_decimal_fraction, ieee_number, exponent10, digits, p)
893 #define ieee_float_decimal(ieee_number, exponent10, digits, p) \
894  ieee_number_decimal(ieee_float_decimal_fraction, ieee_number, exponent10, digits, p)
895 
896 #endif
897 
898 #define ieee_number_decimal(method, ieee_number, exponent10, digits, p) \
899  ieee_double_denormalize(ieee_number); \
900  if (ieee_number.sign) *p++ = '-'; \
901  if (exponent10 <= 0) \
902  for (*p++ = '0', *p++ = RADIX_CHAR; exponent10 && digits; *p++ = '0', ++exponent10, --digits); \
903  else \
904  { \
905  do { *p++ = '0' + (char)method(ieee_number); } while (--exponent10); \
906  *p++ = RADIX_CHAR; \
907  } \
908  for ( ; digits && ieee_number.fraction; --digits) \
909  *p++ = '0' + (char)method(ieee_number)
910 
911 /* rounding to nearest integer */
912 
913 #if BINARY_MODF
914 /* check if the mantissa has the most significant bit set, means >= 0.5 */
915 # define ieee_double_half(ieee_number) (ieee_number.fraction & (1ull<<55))
916 # define ieee_float_half(ieee_number) (ieee_number.fraction & (1<<26))
917 #else
918 # define ieee_double_half(ieee_number) (ieee_number.number >= 0.5)
919 # define ieee_float_half(ieee_number) (ieee_number.number >= 0.5)
920 #endif
921 
922 /* rounding to nearest integer */
923 
924 #define buffer_ceil(s, p, sign) \
925  { \
926  while (*--p == '9'); \
927  if (*p != RADIX_CHAR) ++*p++; \
928  else { \
929  char *q; \
930  for (q = p - 1; ; --q) { \
931  if (*q < '9') { ++*q; break; } \
932  *q = '0'; \
933  if (q == s) \
934  *--s = '1'; \
935  else if (sign && q - 1 == s) \
936  *s = '1', *--s = '-'; \
937  } \
938  } \
939  }
940 
941 #define buffer_remove_trailing_zeros(s, p, sign) \
942  { \
943  while (*--p == '0'); \
944  if (*p != RADIX_CHAR) \
945  ++p; \
946  else if (!SIGNED_ZERO && sign && p - 2 == s && *(p - 1) == '0') \
947  p -= 2, *p++ = '0'; \
948  }
949 
950 // if digits parameter was initially less then exponent10, then exponent10 > 0 and ieee_double_half(ieee_number) is irrelevant
951 #define ieee_double_round(ieee_number, exponent10, s, p) \
952  if (exponent10 == 0 && ieee_double_half(ieee_number)) \
953  { buffer_ceil(s, p, ieee_number.sign); } \
954  else \
955  { buffer_remove_trailing_zeros(s, p, ieee_number.sign); }
956 
957 #define ieee_float_round(ieee_number, exponent10, s, p) \
958  if (exponent10 == 0 && ieee_float_half(ieee_number)) \
959  { buffer_ceil(s, p, ieee_number.sign); } \
960  else \
961  { buffer_remove_trailing_zeros(s, p, ieee_number.sign); }
962 
963 /* double to decimal */
964 
965 #define ieee_copy_special_string(nbuf, special, p, _p) \
966  for (p = nbuf, _p = special; ; ++p, ++_p) { \
967  if ((*p = *_p) == '\0') break; \
968  }
969 
970 #define ieee_copy_special_string_re(nbuf, special, p, _p, r, e) \
971  for (p = nbuf, _p = special; ; ++p, ++_p) { \
972  if ((*p = *_p) == '\0') { \
973  if (r != NULL) *r = NULL; \
974  if (e != NULL) *e = p; \
975  break; \
976  } \
977  }
978 
979 char * double_as_string (double number, int digits, char nbuf[MAX_NUMBER_DIGITS], size_t *psize)
980 {
981  ieee_double ieee_number;
982  int exponent10;
983  char *s, *p; const char *_p;
984  s = p = nbuf + 1; // for sign/rounding
985  ieee_double_init(ieee_number, number);
986  if ((ieee_number.sign = ieee_number.bits >> 63) != 0)
987  ieee_number.number = -ieee_number.number;
988  if (ieee_double_is_zero(ieee_number)) // to avoid crash on log10(number)
989  {
991  *psize = (size_t)(p - nbuf);
992  return nbuf;
993  }
994  if (ieee_double_special_case(ieee_number))
995  {
997  *psize = (size_t)(p - nbuf);
998  return nbuf;
999  }
1000  ieee_double_exp10(ieee_number, exponent10);
1001  ieee_double_decimal(ieee_number, exponent10, digits, p);
1002  ieee_double_round(ieee_number, exponent10, s, p);
1003  *p = '\0';
1004  *psize = (size_t)(p - s);
1005  return s;
1006 }
1007 
1008 /* float to decimal */
1009 
1010 char * float_as_string (float number, int digits, char nbuf[MAX_NUMBER_DIGITS], size_t *psize)
1011 {
1012  ieee_float ieee_number;
1013  int exponent10;
1014  char *s, *p; const char *_p;
1015  s = p = nbuf + 1; // for sign/rounding
1016  ieee_float_init(ieee_number, number);
1017  if ((ieee_number.sign = ieee_number.bits >> 31) != 0)
1018  ieee_number.number = -ieee_number.number;
1019  if (ieee_float_is_zero(ieee_number))
1020  {
1022  *psize = (size_t)(p - nbuf);
1023  return nbuf;
1024  }
1025  if (ieee_float_special_case(ieee_number))
1026  {
1028  *psize = (size_t)(p - nbuf);
1029  return nbuf;
1030  }
1031  ieee_float_exp10(ieee_number, exponent10);
1032  ieee_float_decimal(ieee_number, exponent10, digits, p);
1033  ieee_float_round(ieee_number, exponent10, s, p);
1034  *p = '\0';
1035  *psize = (size_t)(p - s);
1036  return s;
1037 }
1038 
1039 /* decimal string to double/float */
1040 
1041 #define string_scan_decimal(s, c, number) _scan_decimal(c, number, *++s)
1042 #define string_scan_fraction(s, c, number, exponent10) _scan_fraction(c, number, exponent10, *++s)
1043 #define string_scan_exponent10(s, c, exponent10) _scan_exponent10(c, exponent10, *++s)
1044 
1045 const char * string_to_double (const char *s, double *number)
1046 {
1047  int sign, exponent10, c = *s;
1048  string_scan_sign(s, c, sign);
1050  if (c == '.')
1051  {
1052  c = *++s;
1053  string_scan_fraction(s, c, *number, exponent10);
1054  }
1055  else
1056  exponent10 = 0;
1057  if (c == 'e' || c == 'E')
1058  {
1059  c = *++s;
1060  string_scan_exponent10(s, c, exponent10);
1061  }
1062  double_exp10(*number, exponent10);
1063  if (sign) *number = -*number;
1064  return s;
1065 }
1066 
1067 const char * string_to_float (const char *s, float *number)
1068 {
1069  int sign, exponent10, c = *s;
1070  string_scan_sign(s, c, sign);
1072  if (c == '.')
1073  {
1074  c = *++s;
1075  string_scan_fraction(s, c, *number, exponent10);
1076  }
1077  else
1078  exponent10 = 0;
1079  if (c == 'e' || c == 'E')
1080  {
1081  c = *++s;
1082  string_scan_exponent10(s, c, exponent10);
1083  }
1084  float_exp10(*number, exponent10);
1085  if (sign) *number = -*number;
1086  return s;
1087 }
1088 
1089 /* conventional form */
1090 
1091 const char * convert_to_double (const char *s, double *number)
1092 {
1093  int sign, c = *s;
1094  string_scan_sign(s, c, sign);
1096  if (c == '.' || c == ',')
1097  {
1098  int exponent10;
1099  c = *++s;
1100  string_scan_fraction(s, c, *number, exponent10);
1101  if (exponent10 < 0)
1102  double_negative_exp10(*number, exponent10);
1103  }
1104  if (sign) *number = -*number;
1105  return s;
1106 }
1107 
1108 const char * convert_to_float (const char *s, float *number)
1109 {
1110  int sign, c = *s;
1111  string_scan_sign(s, c, sign);
1113  if (c == '.' || c == ',')
1114  {
1115  int exponent10;
1116  c = *++s;
1117  string_scan_fraction(s, c, *number, exponent10);
1118  if (exponent10 < 0)
1119  float_negative_exp10(*number, exponent10);
1120  }
1121  if (sign) *number = -*number;
1122  return s;
1123 }
1124 
1125 /* pretty common stuff */
1126 
1127 size_t bytes_to_hex_lc (const void *input, size_t size, unsigned char *output)
1128 {
1129  size_t i;
1130  const unsigned char *p;
1131  for (i = 0, p = (const unsigned char *)input; i < size; ++i, ++p)
1132  {
1133  *output++ = base16_lc_digit1(*p);
1134  *output++ = base16_lc_digit2(*p);
1135  }
1136  *output = '\0';
1137  return 2*size + 1;
1138 }
1139 
1140 size_t bytes_to_hex_uc (const void *input, size_t size, unsigned char *output)
1141 {
1142  size_t i;
1143  const unsigned char *p;
1144  for (i = 0, p = (const unsigned char *)input; i < size; ++i, ++p)
1145  {
1146  *output++ = base16_uc_digit1(*p);
1147  *output++ = base16_uc_digit2(*p);
1148  }
1149  *output = '\0';
1150  return 2*size + 1;
1151 }
1152 
1153 size_t hex_to_bytes (const void *input, size_t size, unsigned char *output)
1154 {
1155  size_t i;
1156  int c1, c2;
1157  const unsigned char *p;
1158  for (i = 1, p = (const unsigned char *)input; i < size; i += 2)
1159  {
1160  c1 = base16_value(*p);
1161  ++p;
1162  c2 = base16_value(*p);
1163  ++p;
1164  if (c1 >= 0 && c2 >= 0)
1165  *output++ = (unsigned char)((c1<<4)|c2);
1166  else
1167  break;
1168  }
1169  return i >> 1;
1170 }
1171 
1172 void print_as_hex (const void *input, size_t bytes)
1173 {
1174  const unsigned char *p;
1175  for (p = (const unsigned char *)input; bytes > 0; --bytes, ++p)
1176  printf("%02x", *p);
1177 }
static int radix
Definition: aptex.h:450
#define n
Definition: t4ht.c:1290
int v
Definition: dviconv.c:10
int printf()
#define s
Definition: afcover.h:80
#define c(n)
Definition: gpos-common.c:150
static char nbuf[100]
Definition: hpcdtoppm.c:135
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
unsigned short uint16_t
Definition: stdint.h:79
signed __int64 int64_t
Definition: stdint.h:89
unsigned int uint32_t
Definition: stdint.h:80
signed int int32_t
Definition: stdint.h:77
unsigned __int64 uint64_t
Definition: stdint.h:90
int alphabet(char c)
Definition: sort.c:230
#define size_t
Definition: glob.c:257
int k
Definition: otp-parser.c:70
unsigned digits[12]
Definition: out_routines.c:255
#define sign(x)
static int size
Definition: ppmlabel.c:24
char ibuf[32000]
Definition: ps_tiny.c:177
static long bytes
Definition: psutil.c:35
const char * radix_to_usize(const char *s, size_t *number, int radix)
Definition: utilnumber.c:195
const char * radix_to_uint64(const char *s, uint64_t *number, int radix)
Definition: utilnumber.c:202
const int base36_lookup[]
Definition: utilnumber.c:68
const int base26_lookup[]
Definition: utilnumber.c:49
size_t bytes_to_hex_lc(const void *input, size_t size, unsigned char *output)
Definition: utilnumber.c:1127
const char * string_to_int64(const char *s, int64_t *number)
Definition: utilnumber.c:117
char * int32_as_radix(int32_t number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:423
const char * radix_to_slong(const char *s, long *number, int radix)
Definition: utilnumber.c:163
char * uint16_as_roman(uint16_t number, int uc, char ibuf[128], size_t *psize)
Definition: utilnumber.c:606
const char * roman_to_uint16(const char *s, uint16_t *number)
Definition: utilnumber.c:223
const double double_decimal_negpower10[]
Definition: utilnumber.c:779
char * int64_as_string(int64_t number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:340
const char * alpha_to_uint64(const char *s, uint64_t *number)
Definition: utilnumber.c:499
char * usize_as_string(size_t number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:358
const float float_decimal_power10[]
Definition: utilnumber.c:772
const char * alphan_to_uint16(const char *s, uint16_t *number)
Definition: utilnumber.c:562
char * ulong_as_radix(unsigned long number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:455
const char * string_to_uint32(const char *s, uint32_t *number)
Definition: utilnumber.c:126
const int base16_lookup[]
Definition: utilnumber.c:30
const int base10_lookup[]
Definition: utilnumber.c:11
const float float_decimal_negpower10[]
Definition: utilnumber.c:813
char * slong_as_string(long number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:334
const char * string_to_uint64(const char *s, uint64_t *number)
Definition: utilnumber.c:147
char * uint32_as_radix(uint32_t number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:449
char util_number_buffer[512]
Definition: utilnumber.c:89
size_t hex_to_bytes(const void *input, size_t size, unsigned char *output)
Definition: utilnumber.c:1153
size_t bytes_to_hex_uc(const void *input, size_t size, unsigned char *output)
Definition: utilnumber.c:1140
char * uint32_as_alpha(uint32_t number, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:526
char * int32_as_string(int32_t number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:328
char * uint32_as_string(uint32_t number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:346
const char * radix_to_ulong(const char *s, unsigned long *number, int radix)
Definition: utilnumber.c:188
char * ulong_as_alpha(unsigned long number, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:532
const char * radix_to_uint32(const char *s, uint32_t *number, int radix)
Definition: utilnumber.c:181
char * double_as_string(double number, int digits, char nbuf[512], size_t *psize)
Definition: utilnumber.c:979
char * usize_as_alpha(size_t number, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:538
const char * radix_to_int32(const char *s, int32_t *number, int radix)
Definition: utilnumber.c:154
const char * string_to_double(const char *s, double *number)
Definition: utilnumber.c:1045
const char * alpha_to_usize(const char *s, size_t *number)
Definition: utilnumber.c:492
struct ieee_float ieee_float
const char * alpha_to_uint32(const char *s, uint32_t *number)
Definition: utilnumber.c:478
char * usize_as_radix(size_t number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:461
const char * convert_to_float(const char *s, float *number)
Definition: utilnumber.c:1108
void print_as_hex(const void *input, size_t bytes)
Definition: utilnumber.c:1172
const double double_decimal_power10[]
Definition: utilnumber.c:738
const char * string_to_slong(const char *s, long *number)
Definition: utilnumber.c:108
char * uint64_as_string(uint64_t number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:364
char * uint16_as_alphan(uint16_t number, int uc, char ibuf[], size_t size, size_t *psize)
Definition: utilnumber.c:593
struct ieee_double ieee_double
char * uint64_as_alpha(uint64_t number, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:544
const char * alpha_to_ulong(const char *s, unsigned long *number)
Definition: utilnumber.c:485
char * uint64_as_radix(uint64_t number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:467
char * ulong_as_string(unsigned long number, char ibuf[65], size_t *psize)
Definition: utilnumber.c:352
char * slong_as_radix(long number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:429
const char * string_to_int32(const char *s, int32_t *number)
Definition: utilnumber.c:99
char * float_as_string(float number, int digits, char nbuf[512], size_t *psize)
Definition: utilnumber.c:1010
const char * convert_to_double(const char *s, double *number)
Definition: utilnumber.c:1091
const char * string_to_usize(const char *s, size_t *number)
Definition: utilnumber.c:140
const char * radix_to_int64(const char *s, int64_t *number, int radix)
Definition: utilnumber.c:172
const char * string_to_ulong(const char *s, unsigned long *number)
Definition: utilnumber.c:133
const char * string_to_float(const char *s, float *number)
Definition: utilnumber.c:1067
char * int64_as_radix(int64_t number, int radix, int uc, char ibuf[65], size_t *psize)
Definition: utilnumber.c:443
#define MAX_NUMBER_DIGITS
Definition: utilnumber.h:65
#define double_negative_exp10(number, exponent)
Definition: utilnumber.h:409
#define double_exp10(number, exponent)
Definition: utilnumber.h:415
#define float_negative_exp10(number, exponent)
Definition: utilnumber.h:412
#define MAX_INTEGER_DIGITS
Definition: utilnumber.h:63
#define MAX_ROMAN_DIGITS
Definition: utilnumber.h:64
#define float_exp10(number, exponent)
Definition: utilnumber.h:416
#define base16_uc_digit1(c)
Definition: utilnumber.h:88
#define base16_uc_digit2(c)
Definition: utilnumber.h:89
#define NUMBER_BUFFER_SIZE
Definition: utilnumber.h:66
#define base16_lc_digit2(c)
Definition: utilnumber.h:91
#define base16_value(c)
Definition: utilnumber.h:100
#define base16_lc_digit1(c)
Definition: utilnumber.h:90
#define ieee_double_is_zero(ieee_number)
Definition: utilnumber.c:696
#define base_roman_lc_alphabet
Definition: utilnumber.c:604
#define ieee_float_is_zero(ieee_number)
Definition: utilnumber.c:699
#define ieee_float_decimal(ieee_number, exponent10, digits, p)
Definition: utilnumber.c:881
#define roman500(c)
Definition: utilnumber.c:212
#define string_scan_decimal(s, c, number)
Definition: utilnumber.c:1041
#define UINTTYPE_AS_ALPHA(inttype, number, uc, ibuf, psize)
Definition: utilnumber.c:518
#define SINTTYPE_AS_STRING(inttype, number, ibuf, psize)
Definition: utilnumber.c:314
#define roman1(c)
Definition: utilnumber.c:217
#define string_scan_radix(s, c, number, radix)
Definition: utilnumber.c:95
#define ieee_float_special_case(ieee_number)
Definition: utilnumber.c:711
#define string_scan_alpha(s, c, number, radix)
Definition: utilnumber.c:475
#define string_scan_exponent10(s, c, exponent10)
Definition: utilnumber.c:1043
#define UINTTYPE_AS_RADIX(inttype, number, radix, uc, ibuf, psize)
Definition: utilnumber.c:416
#define string_scan_integer(s, c, number)
Definition: utilnumber.c:94
#define ieee_float_zero_string
Definition: utilnumber.c:705
#define ieee_copy_special_string(nbuf, special, p, _p)
Definition: utilnumber.c:965
#define UINTTYPE_AS_ALPHAN(inttype, number, uc, ibuf, size, psize)
Definition: utilnumber.c:581
#define ieee_double_decimal(ieee_number, exponent10, digits, p)
Definition: utilnumber.c:879
#define roman100s(p)
Definition: utilnumber.c:219
#define roman50(c)
Definition: utilnumber.c:214
#define string_scan_alphan(s, c, number, radix)
Definition: utilnumber.c:553
#define UINTTYPE_AS_STRING(inttype, number, ibuf, psize)
Definition: utilnumber.c:321
#define string_scan_fraction(s, c, number, exponent10)
Definition: utilnumber.c:1042
#define roman1s(p)
Definition: utilnumber.c:221
#define ieee_float_init(ieee_number, number)
Definition: utilnumber.c:689
#define ieee_float_exp10(ieee_number, exponent10)
Definition: utilnumber.c:839
#define ieee_float_round(ieee_number, exponent10, s, p)
Definition: utilnumber.c:957
#define roman5(c)
Definition: utilnumber.c:216
#define base_roman_uc_alphabet
Definition: utilnumber.c:603
#define ieee_double_round(ieee_number, exponent10, s, p)
Definition: utilnumber.c:951
#define string_scan_sign(s, c, sign)
Definition: utilnumber.c:93
#define ieee_double_init(ieee_number, number)
Definition: utilnumber.c:682
#define roman100(c)
Definition: utilnumber.c:213
#define ieee_double_special_string(ieee_number)
Definition: utilnumber.c:709
#define roman10s(p)
Definition: utilnumber.c:220
#define ieee_float_special_string(ieee_number)
Definition: utilnumber.c:712
#define roman1000(c)
Definition: utilnumber.c:211
#define ieee_double_special_case(ieee_number)
Definition: utilnumber.c:708
#define ieee_double_zero_string(ieee_number)
Definition: utilnumber.c:702
#define SINTTYPE_AS_RADIX(inttype, number, radix, uc, ibuf, psize)
Definition: utilnumber.c:409
#define roman10(c)
Definition: utilnumber.c:215
#define ieee_double_exp10(ieee_number, exponent10)
Definition: utilnumber.c:827
#define uint32_t
Definition: stdint.in.h:168
uint64_t fraction
Definition: utilnumber.c:659
uint64_t bits
Definition: utilnumber.c:657
double number
Definition: utilnumber.c:656
uint32_t fraction
Definition: utilnumber.c:668
uint32_t bits
Definition: utilnumber.c:666
float number
Definition: utilnumber.c:665
int exponent
Definition: utilnumber.c:669
Definition: execute.c:108
Definition: output.h:18
#define c2
Definition: t1io.c:53
#define c1
Definition: t1io.c:52
int number
Definition: t1part.c:207
int j
Definition: t4ht.c:1589