#include "to_numeral.h"
std::string aszNumeral;
int iNum = -13456737;
to_numeral<int, char, ru_lower_locale_tag>(iNum, aszNumeral);
// aszNumeral = "минус тринадцать миллионов четыреста пятьдесят шесть тысяч семьсот тридцать семь "
std::wstring wszNumeral;
__int64 i64Num = 13134563467;
to_numeral<__int64, wchar_t, ru_upper_locale_tag>(i64Num, wszNumeral);
// wszNumeral = "ТРИНАДЦАТЬ МИЛЛИАРДОВ СТО ТРИДЦАТЬ ЧЕТЫРЕ МИЛЛИОНА ПЯТЬСОТ ШЕСТЬДЕСЯТ ТРИ ТЫСЯЧИ ЧЕТЫРЕСТА ШЕСТЬДЕСЯТ СЕМЬ "
//////////////////////////////////////////////////////////////////////////////////////////
//
// ru_lower_locale.h
//
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __RU_LOWER_LOCALE_H__
#define __RU_LOWER_LOCALE_H__
#pragma once
//////////////////////////////////////////////////////////////////////////////////////////
struct ru_lower_locale_tag { };
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
template <>
const char*** ToNumeralLocale<char, ru_lower_locale_tag>(void)
{
typedef char char_type;
static const char_type* g_pServiceArr[] =
{ "ноль", "минус " };
static const char_type* g_pFirstNumeralArr[] =
{ "один ", "одиннадцать ", "десять ", "сто ", "одна " };
static const char_type* g_pSecondNumeralArr[] =
{ "два ", "двенадцать ", "двадцать ", "двести ", "две " };
static const char_type* g_pThirdNumeralArr[] =
{ "три ", "тринадцать ", "тридцать ", "триста " };
static const char_type* g_pFourthNumeralArr[] =
{ "четыре ", "четырнадцать ", "сорок ", "четыреста " };
static const char_type* g_pFifthNumeralArr[] =
{ "пять ", "пятнадцать ", "пятьдесят ", "пятьсот " };
static const char_type* g_pSixthNumeralArr[] =
{ "шесть ", "шестнадцать ", "шестьдесят ", "шестьсот " };
static const char_type* g_pSeventhNumeralArr[] =
{ "семь ", "семнадцать ", "семьдесят ", "семьсот " };
static const char_type* g_pEighthNumeralArr[] =
{ "восемь ", "восемнадцать ", "восемьдесят ","восемьсот " };
static const char_type* g_pNinthNumeralArr[] =
{ "девять ", "девятнадцать ", "девяносто ", "девятьсот " };
static const char_type* g_pFirstTriadArr[] =
{ "тысяча ", "тысячи ", "тысяч " };
static const char_type* g_pSecondTriadArr[] =
{ "миллион ", "миллиона ", "миллионов " };
static const char_type* g_pThirdTriadArr[] =
{ "миллиард ", "миллиарда ", "миллиардов " };
static const char_type* g_pFourthTriadArr[] =
{ "триллион ", "триллиона ", "триллионов " };
static const char_type* g_pFifthTriadArr[] =
{ "триллиард ","триллиарда ", "триллиардов " };
static const char_type** g_NumeralLocale[] =
{
g_pServiceArr,
g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
g_pFourthTriadArr, g_pFifthTriadArr
};
return g_NumeralLocale;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
template <>
const wchar_t*** ToNumeralLocale<wchar_t, ru_lower_locale_tag>(void)
{
typedef wchar_t char_type;
static const char_type* g_pServiceArr[] =
{ L"ноль", L"минус " };
static const char_type* g_pFirstNumeralArr[] =
{ L"один ", L"одиннадцать ", L"десять ", L"сто ", L"одна " };
static const char_type* g_pSecondNumeralArr[] =
{ L"два ", L"двенадцать ", L"двадцать ", L"двести ", L"две " };
static const char_type* g_pThirdNumeralArr[] =
{ L"три ", L"тринадцать ", L"тридцать ", L"триста " };
static const char_type* g_pFourthNumeralArr[] =
{ L"четыре ", L"четырнадцать ", L"сорок ", L"четыреста " };
static const char_type* g_pFifthNumeralArr[] =
{ L"пять ", L"пятнадцать ", L"пятьдесят ", L"пятьсот " };
static const char_type* g_pSixthNumeralArr[] =
{ L"шесть ", L"шестнадцать ", L"шестьдесят ", L"шестьсот " };
static const char_type* g_pSeventhNumeralArr[] =
{ L"семь ", L"семнадцать ", L"семьдесят ", L"семьсот " };
static const char_type* g_pEighthNumeralArr[] =
{ L"восемь ", L"восемнадцать ", L"восемьдесят ",L"восемьсот " };
static const char_type* g_pNinthNumeralArr[] =
{ L"девять ", L"девятнадцать ", L"девяносто ", L"девятьсот " };
static const char_type* g_pFirstTriadArr[] =
{ L"тысяча ", L"тысячи ", L"тысяч " };
static const char_type* g_pSecondTriadArr[] =
{ L"миллион ", L"миллиона ", L"миллионов " };
static const char_type* g_pThirdTriadArr[] =
{ L"миллиард ", L"миллиарда ", L"миллиардов " };
static const char_type* g_pFourthTriadArr[] =
{ L"триллион ", L"триллиона ", L"триллионов " };
static const char_type* g_pFifthTriadArr[] =
{ L"триллиард ",L"триллиарда ", L"триллиардов " };
static const char_type** g_NumeralLocale[] =
{
g_pServiceArr,
g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
g_pFourthTriadArr, g_pFifthTriadArr
};
return g_NumeralLocale;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
#endif // __RU_LOWER_LOCALE_H__
//////////////////////////////////////////////////////////////////////////////////////////
//
// ru_upper_locale.h
//
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __RU_UPPER_LOCALE_H__
#define __RU_UPPER_LOCALE_H__
#pragma once
//////////////////////////////////////////////////////////////////////////////////////////
struct ru_upper_locale_tag { };
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
template <>
const char*** ToNumeralLocale<char, ru_upper_locale_tag>(void)
{
typedef char char_type;
static const char_type* g_pServiceArr[] =
{ "НОЛЬ", "МИНУС " };
static const char_type* g_pFirstNumeralArr[] =
{ "ОДИН ", "ОДИННАДЦАТЬ ", "ДЕСЯТЬ ", "СТО ", "ОДНА " };
static const char_type* g_pSecondNumeralArr[] =
{ "ДВА ", "ДВЕНАДЦАТЬ ", "ДВАДЦАТЬ ", "ДВЕСТИ ", "ДВЕ " };
static const char_type* g_pThirdNumeralArr[] =
{ "ТРИ ", "ТРИНАДЦАТЬ ", "ТРИДЦАТЬ ", "ТРИСТА " };
static const char_type* g_pFourthNumeralArr[] =
{ "ЧЕТЫРЕ ", "ЧЕТЫРНАДЦАТЬ ", "СОРОК ", "ЧЕТЫРЕСТА " };
static const char_type* g_pFifthNumeralArr[] =
{ "ПЯТЬ ", "ПЯТНАДЦАТЬ ", "ПЯТЬДЕСЯТ ", "ПЯТЬСОТ " };
static const char_type* g_pSixthNumeralArr[] =
{ "ШЕСТЬ ", "ШЕСТНАДЦАТЬ ", "ШЕСТЬДЕСЯТ ", "ШЕСТЬСОТ " };
static const char_type* g_pSeventhNumeralArr[] =
{ "СЕМЬ ", "СЕМНАДЦАТЬ ", "СЕМЬДЕСЯТ ", "СЕМЬСОТ " };
static const char_type* g_pEighthNumeralArr[] =
{ "ВОСЕМЬ ", "ВОСЕМНАДЦАТЬ ", "ВОСЕМЬДЕСЯТ ","ВОСЕМЬСОТ " };
static const char_type* g_pNinthNumeralArr[] =
{ "ДЕВЯТЬ ", "ДЕВЯТНАДЦАТЬ ", "ДЕВЯНОСТО ", "ДЕВЯТЬСОТ " };
static const char_type* g_pFirstTriadArr[] =
{ "ТЫСЯЧА ", "ТЫСЯЧИ ", "ТЫСЯЧ " };
static const char_type* g_pSecondTriadArr[] =
{ "МИЛЛИОН ", "МИЛЛИОНА ", "МИЛЛИОНОВ " };
static const char_type* g_pThirdTriadArr[] =
{ "МИЛЛИАРД ", "МИЛЛИАРДА ", "МИЛЛИАРДОВ " };
static const char_type* g_pFourthTriadArr[] =
{ "ТРИЛЛИОН ", "ТРИЛЛИОНА ", "ТРИЛЛИОНОВ " };
static const char_type* g_pFifthTriadArr[] =
{ "ТРИЛЛИАРД ","ТРИЛЛИАРДА ", "ТРИЛЛИАРДОВ " };
static const char_type** g_NumeralLocale[] =
{
g_pServiceArr,
g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
g_pFourthTriadArr, g_pFifthTriadArr
};
return g_NumeralLocale;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
template <>
const wchar_t*** ToNumeralLocale<wchar_t, ru_upper_locale_tag>(void)
{
typedef wchar_t char_type;
static const char_type* g_pServiceArr[] =
{ L"НОЛЬ", L"МИНУС " };
static const char_type* g_pFirstNumeralArr[] =
{ L"ОДИН ", L"ОДИННАДЦАТЬ ", L"ДЕСЯТЬ ", L"СТО ", L"ОДНА " };
static const char_type* g_pSecondNumeralArr[] =
{ L"ДВА ", L"ДВЕНАДЦАТЬ ", L"ДВАДЦАТЬ ", L"ДВЕСТИ ", L"ДВЕ " };
static const char_type* g_pThirdNumeralArr[] =
{ L"ТРИ ", L"ТРИНАДЦАТЬ ", L"ТРИДЦАТЬ ", L"ТРИСТА " };
static const char_type* g_pFourthNumeralArr[] =
{ L"ЧЕТЫРЕ ", L"ЧЕТЫРНАДЦАТЬ ", L"СОРОК ", L"ЧЕТЫРЕСТА " };
static const char_type* g_pFifthNumeralArr[] =
{ L"ПЯТЬ ", L"ПЯТНАДЦАТЬ ", L"ПЯТЬДЕСЯТ ", L"ПЯТЬСОТ " };
static const char_type* g_pSixthNumeralArr[] =
{ L"ШЕСТЬ ", L"ШЕСТНАДЦАТЬ ", L"ШЕСТЬДЕСЯТ ", L"ШЕСТЬСОТ " };
static const char_type* g_pSeventhNumeralArr[] =
{ L"СЕМЬ ", L"СЕМНАДЦАТЬ ", L"СЕМЬДЕСЯТ ", L"СЕМЬСОТ " };
static const char_type* g_pEighthNumeralArr[] =
{ L"ВОСЕМЬ ", L"ВОСЕМНАДЦАТЬ ", L"ВОСЕМЬДЕСЯТ ",L"ВОСЕМЬСОТ " };
static const char_type* g_pNinthNumeralArr[] =
{ L"ДЕВЯТЬ ", L"ДЕВЯТНАДЦАТЬ ", L"ДЕВЯНОСТО ", L"ДЕВЯТЬСОТ " };
static const char_type* g_pFirstTriadArr[] =
{ L"ТЫСЯЧА ", L"ТЫСЯЧИ ", L"ТЫСЯЧ " };
static const char_type* g_pSecondTriadArr[] =
{ L"МИЛЛИОН ", L"МИЛЛИОНА ", L"МИЛЛИОНОВ " };
static const char_type* g_pThirdTriadArr[] =
{ L"МИЛЛИАРД ", L"МИЛЛИАРДА ", L"МИЛЛИАРДОВ " };
static const char_type* g_pFourthTriadArr[] =
{ L"ТРИЛЛИОН ", L"ТРИЛЛИОНА ", L"ТРИЛЛИОНОВ " };
static const char_type* g_pFifthTriadArr[] =
{ L"ТРИЛЛИАРД ",L"ТРИЛЛИАРДА ", L"ТРИЛЛИАРДОВ " };
static const char_type** g_NumeralLocale[] =
{
g_pServiceArr,
g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
g_pFourthTriadArr, g_pFifthTriadArr
};
return g_NumeralLocale;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
#endif // __RU_UPPER_LOCALE_H__
//////////////////////////////////////////////////////////////////////////////////////////
//
// to_numeral_locale.h
//
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __TO_NUMERAL_LOCALE_H__
#define __TO_NUMERAL_LOCALE_H__
#pragma once
//////////////////////////////////////////////////////////////////////////////////////////
template <typename CharType, typename LocaleTag>
const CharType*** ToNumeralLocale(void);
#include "ru_lower_locale.h"
#include "ru_upper_locale.h"
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
template <typename CharType, typename LocaleTag>
struct to_numeral_locale
{
typedef CharType char_type;
typedef LocaleTag locale_tag;
//////////////////////////////////////////////////////////////////////////////////////
static const char_type* Null(void)
{ return ToNumeralLocale<char_type, locale_tag>()[0][0]; }
static const char_type* Minus(void)
{ return ToNumeralLocale<char_type, locale_tag>()[0][1]; }
static const char_type* Numeral(const int ciDigit, const int ciExt)
{ return ToNumeralLocale<char_type, locale_tag>()[ciDigit][ciExt]; }
static const char_type* TriadName(const int ciIndex, const int ciExt)
{ return ToNumeralLocale<char_type, locale_tag>()[9 + ciIndex][ciExt]; }
//////////////////////////////////////////////////////////////////////////////////////
};
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
#endif // __TO_NUMERAL_LOCALE_H__
//////////////////////////////////////////////////////////////////////////////////////////
//
// to_numeral.h
//
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef __TO_NUMERAL_H__
#define __TO_NUMERAL_H__
#pragma once
#include <string>
#include <vector>
#include "to_numeral_locale.h"
//////////////////////////////////////////////////////////////////////////////////////////
template <typename NumType, typename CharType, typename LocaleTag>
class to_numeral
{
public:
typedef NumType num_type;
typedef CharType char_type;
typedef LocaleTag locale_tag;
typedef to_numeral_locale<char_type, locale_tag> locale_type;
typedef std::basic_string<char_type> string;
//////////////////////////////////////////////////////////////////////////////////////
public:
to_numeral(const num_type tNum, string& szOut)
{ Proccess(tNum, szOut); }
private:
to_numeral(void);
to_numeral(const to_numeral&);
//////////////////////////////////////////////////////////////////////////////////////
private:
//////////////////////////////////////////////////////////////////////////////////////
inline void Proccess(const num_type tOrigNum, string& szOut) const
{
if(!tOrigNum) { szOut = locale_type::Null(); return; }
else szOut.clear();
std::vector<int> vDigit;
{
num_type tNum =
(tOrigNum > 0 ? tOrigNum : (szOut = locale_type::Minus(), -tOrigNum));
do { vDigit.push_back(tNum % 10); tNum /= 10; } while(tNum);
}
typedef std::vector<int>::const_iterator const_it;
const_it citCursor = vDigit.end();
// порядок чиса
const int iExp = vDigit.size();
// количество триад
int iTriad = (iExp / 3) - (!(iExp % 3) ? 1 : 0);
// количество цифр в старшей триаде
int iCount = (iExp - (iTriad * 3));
int iDigit = 0;
int iTriadName = -1;
do
{
do
{
if(!(iDigit = *(--citCursor))) continue;
switch(iCount)
{
//////////////////////////////////////////////////////////////////////////
case 1: // единицы
if(iTriad == 1 && iDigit < 3)
szOut += locale_type::Numeral(iDigit, 4);
else
szOut += locale_type::Numeral(iDigit, 0);
switch(iDigit)
{
case 1: iTriadName = 0; break;
case 2:
case 3:
case 4: iTriadName = 1; break;
default: iTriadName = 2; break;
}
break;
//////////////////////////////////////////////////////////////////////////
case 2: // десятки
if(iDigit == 1) // вторая десятка
{
iDigit = *(--citCursor);
if(!iDigit) szOut += locale_type::Numeral(1, 2);
else szOut += locale_type::Numeral(iDigit, 1);
--iCount;
}
else
szOut += locale_type::Numeral(iDigit, 2);
iTriadName = 2;
break;
//////////////////////////////////////////////////////////////////////////
case 3: // сотни
szOut += locale_type::Numeral(iDigit, 3);
iTriadName = 2;
break;
//////////////////////////////////////////////////////////////////////////
}
}
while(--iCount);
if(!iTriad) return;
if(iTriadName != -1) szOut += locale_type::TriadName(iTriad, iTriadName);
iTriadName = -1;
iCount = 3;
--iTriad;
}
while(true);
}
//////////////////////////////////////////////////////////////////////////////////////
};
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
#endif // __TO_NUMERAL_H__