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