4 #include "base/cl_sysdep.h"
7 #include "real/format-output/cl_format.h"
13 #include "cln/integer.h"
14 #include "cln/integer_io.h"
15 #include "cln/exception.h"
19 void format_new_roman (std::ostream& stream, const cl_I& arg)
21 if (!(0 < arg && arg < 4000)) {
22 std::ostringstream buf;
23 fprint(buf, "format_new_roman: argument should be in the range 1 - 3999, not ");
26 throw runtime_exception(buf.str());
28 var uintL value = cl_I_to_UL(arg);
29 struct roman { char symbol; uintL value; };
30 static const roman scale[7] = {
39 for (int i = 6; value > 0 /* && i >= 0 */ ; i--) {
40 var const roman * p = &scale[i];
41 var uintL multiplicity = floor(value,p->value);
42 value = value % p->value;
43 while (multiplicity > 0) {
44 fprintchar(stream,p->symbol);
49 // Must have i > 0 here.
50 var const roman * p_minor = &scale[(i-1) & ~1];
51 var uintL lowered_value = p->value - p_minor->value;
52 if (value >= lowered_value) {
53 fprintchar(stream,p_minor->symbol);
54 fprintchar(stream,p->symbol);
55 value = value - lowered_value;