You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

138 lines
2.9 KiB

// format_cardinal().
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cl_format.h"
// Implementation.
#include "cln/integer.h"
#include "cln/integer_io.h"
#include "cln/abort.h"
namespace cln {
static const char * const cl_format_ones [20] = {
NULL,
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
};
// gibt eine ganze Zahl >0, <1000 im Klartext auf englisch auf den stream aus.
// (arg=0 -> gibt nichts aus.)
static void format_small_cardinal (std::ostream& stream, uintL arg)
{
var uintL hundreds = floor(arg,100);
var uintL tens_and_ones = arg % 100;
if (hundreds > 0) {
fprint(stream,cl_format_ones[hundreds]);
fprint(stream," hundred");
}
if (tens_and_ones > 0) {
if (hundreds > 0)
fprint(stream," and ");
var uintL tens = floor(tens_and_ones,10);
var uintL ones = tens_and_ones % 10;
if (tens < 2)
fprint(stream,cl_format_ones[tens_and_ones]);
else {
fprint(stream,cl_format_tens[tens]);
if (ones > 0) {
fprintchar(stream,'-');
fprint(stream,cl_format_ones[ones]);
}
}
}
}
void format_cardinal (std::ostream& stream, const cl_I& argument)
{
if (zerop(argument))
fprint(stream,"zero");
else {
var cl_I arg = argument;
if (minusp(arg)) {
fprint(stream,"minus ");
arg = -arg;
}
// amerikanisch (billion=10^9)
static const char * const illions[] = {
"",
" thousand",
" million",
" billion",
" trillion",
" quadrillion",
" quintillion",
" sextillion",
" septillion",
" octillion",
" nonillion",
" decillion",
" undecillion",
" duodecillion",
" tredecillion",
" quattuordecillion",
" quindecillion",
" sexdecillion",
" septendecillion",
" octodecillion",
" novemdecillion",
" vigintillion",
NULL
};
var uintL small_pieces [sizeof(illions)/sizeof(illions[0])];
// Let the recursion begin.
var const char * const * illion_ptr = &illions[0];
var uintL * small_piece_ptr = &small_pieces[0];
do {
if (*illion_ptr == NULL) {
fprint(std::cerr, "format_cardinal: argument too large: ");
fprint(std::cerr, argument);
fprint(std::cerr, "\n");
cl_abort();
}
var cl_I_div_t div = floor2(arg,1000);
var const cl_I& thousands = div.quotient;
var uintL small = cl_I_to_UL(div.remainder);
illion_ptr++;
*small_piece_ptr++ = small;
arg = thousands;
} while (arg > 0);
// Roll back the recursion.
var cl_boolean first_piece = cl_true;
do {
var uintL small = *--small_piece_ptr;
var const char * illion = *--illion_ptr;
if (small > 0) {
if (!first_piece)
fprint(stream,", ");
format_small_cardinal(stream,small);
fprint(stream,illion);
first_piece = cl_false;
}
} until (illion_ptr == &illions[0]);
}
}
} // namespace cln