"I have a checkmate in 117 moves."
vs
"I have a checkmate in one hundred seventeen moves."
You'd rather have your program output the latter instead of the former. And if you are coding in C++, I've got something that will help.
Spell.h:
Code: Select all
#ifndef IncludeSpell
#define IncludeSpell
typedef signed int si;
typedef unsigned int ui;
typedef signed long long int si64;
typedef unsigned long long int ui64;
std::string SpellCardinalDuo(const ui value);
std::string SpellCardinalTriad(const ui value);
std::string SpellCardinalUi64(const ui64 value);
std::string SpellCardinalSi64(const si64 value);
#endif
Code: Select all
#include <sstream>
#include "Spell.h"
static const char *units[10] =
{
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine"
};
static const char *teens[10] =
{
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen"
};
static const char *decades[10] =
{
"zero",
"ten",
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety"
};
std::string SpellCardinalDuo(const ui value)
{
std::ostringstream oss;
if (value >= 20)
{
const ui d0 = value % 10;
oss << decades[value / 10]; if (d0 != 0) oss << '-' << units[d0];
}
else
{
if (value >= 10) oss << teens[value - 10]; else oss << units[value];
};
return oss.str();
}
std::string SpellCardinalTriad(const ui value)
{
std::ostringstream oss;
const ui d2 = value / 100;
if (d2 > 0)
{
const ui residue = value % 100;
oss << units[d2] << ' ' << "hundred";
if (residue > 0) oss << ' ' << SpellCardinalDuo(residue);
}
else
oss << SpellCardinalDuo(value);
return oss.str();
}
std::string SpellCardinalUi64(const ui64 value)
{
std::ostringstream oss;
ui64 residue = value;
bool needspace = false;
const ui64 t3 = 1000;
const ui64 t6 = t3 * 1000;
const ui64 t9 = t6 * 1000;
const ui64 t12 = t9 * 1000;
const ui64 t15 = t12 * 1000;
const ui64 t18 = t15 * 1000;
if (residue >= t18)
{
const ui triad = residue / t18;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " quintillion";
residue -= triad * t18; needspace = (residue != 0);
};
if (residue >= t15)
{
const ui triad = residue / t15;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " quadrillion";
residue -= triad * t15; needspace = (residue != 0);
};
if (residue >= t12)
{
const ui triad = residue / t12;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " trillion";
residue -= triad * t12; needspace = (residue != 0);
};
if (residue >= t9)
{
const ui triad = residue / t9;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " billion";
residue -= triad * t9; needspace = (residue != 0);
};
if (residue >= t6)
{
const ui triad = residue / t6;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " million";
residue -= triad * t6; needspace = (residue != 0);
};
if (residue >= t3)
{
const ui triad = residue / t3;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " thousand";
residue -= triad * t3; needspace = (residue != 0);
};
if ((residue == value) || needspace)
{
const ui triad = residue;
if (needspace) oss << ' '; oss << SpellCardinalTriad(triad);
};
return oss.str();
}
std::string SpellCardinalSi64(const si64 value)
{
std::ostringstream oss;
if (value < 0)
oss << "minus " << SpellCardinalUi64((ui64) -value);
else
oss << SpellCardinalUi64((ui64) value);
return oss.str();
}