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
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
|