]> www.ginac.de Git - cln.git/blob - src/real/format-output/cl_fmt_cardinal.cc
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / real / format-output / cl_fmt_cardinal.cc
1 // format_cardinal().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_format.h"
8
9
10 // Implementation.
11
12 #include "cln/integer.h"
13 #include "cln/integer_io.h"
14 #include "cln/abort.h"
15
16 namespace cln {
17
18 static const char * const cl_format_ones [20] = {
19         NULL,
20         "one",
21         "two",
22         "three",
23         "four",
24         "five",
25         "six",
26         "seven",
27         "eight",
28         "nine",
29         "ten",
30         "eleven",
31         "twelve",
32         "thirteen",
33         "fourteen",
34         "fifteen",
35         "sixteen",
36         "seventeen",
37         "eighteen",
38         "nineteen",
39 };
40
41 // gibt eine ganze Zahl >0, <1000 im Klartext auf englisch auf den stream aus.
42 // (arg=0 -> gibt nichts aus.)
43 static void format_small_cardinal (cl_ostream stream, uintL arg)
44 {
45         var uintL hundreds = floor(arg,100);
46         var uintL tens_and_ones = arg % 100;
47         if (hundreds > 0) {
48                 fprint(stream,cl_format_ones[hundreds]);
49                 fprint(stream," hundred");
50         }
51         if (tens_and_ones > 0) {
52                 if (hundreds > 0)
53                         fprint(stream," and ");
54                 var uintL tens = floor(tens_and_ones,10);
55                 var uintL ones = tens_and_ones % 10;
56                 if (tens < 2)
57                         fprint(stream,cl_format_ones[tens_and_ones]);
58                 else {
59                         fprint(stream,cl_format_tens[tens]);
60                         if (ones > 0) {
61                                 fprintchar(stream,'-');
62                                 fprint(stream,cl_format_ones[ones]);
63                         }
64                 }
65         }
66 }
67
68 void format_cardinal (cl_ostream stream, const cl_I& argument)
69 {
70         if (zerop(argument))
71                 fprint(stream,"zero");
72         else {
73                 var cl_I arg = argument;
74                 if (minusp(arg)) {
75                         fprint(stream,"minus ");
76                         arg = -arg;
77                 }
78                 // amerikanisch (billion=10^9)
79                 static const char * const illions[] = {
80                         "",
81                         " thousand",
82                         " million",
83                         " billion",
84                         " trillion",
85                         " quadrillion",
86                         " quintillion",
87                         " sextillion",
88                         " septillion",
89                         " octillion",
90                         " nonillion",
91                         " decillion",
92                         " undecillion",
93                         " duodecillion",
94                         " tredecillion",
95                         " quattuordecillion",
96                         " quindecillion",
97                         " sexdecillion",
98                         " septendecillion",
99                         " octodecillion",
100                         " novemdecillion",
101                         " vigintillion",
102                         NULL
103                 };
104                 var uintL small_pieces [sizeof(illions)/sizeof(illions[0])];
105                 // Let the recursion begin.
106                 var const char * const * illion_ptr = &illions[0];
107                 var uintL * small_piece_ptr = &small_pieces[0];
108                 do {
109                         if (*illion_ptr == NULL) {
110                                 fprint(stderr, "format_cardinal: argument too large: ");
111                                 fprint(stderr, argument);
112                                 fprint(stderr, "\n");
113                                 cl_abort();
114                         }
115                         var cl_I_div_t div = floor2(arg,1000);
116                         var const cl_I& thousands = div.quotient;
117                         var uintL small = cl_I_to_UL(div.remainder);
118                         illion_ptr++;
119                         *small_piece_ptr++ = small;
120                         arg = thousands;
121                 } while (arg > 0);
122                 // Roll back the recursion.
123                 var cl_boolean first_piece = cl_true;
124                 do {
125                         var uintL small = *--small_piece_ptr;
126                         var const char * illion = *--illion_ptr;
127                         if (small > 0) {
128                                 if (!first_piece)
129                                         fprint(stream,", ");
130                                 format_small_cardinal(stream,small);
131                                 fprint(stream,illion);
132                                 first_piece = cl_false;
133                         }
134                 } until (illion_ptr == &illions[0]);
135         }
136 }
137
138 }  // namespace cln