Pull to refresh

Генерация числа прописью из любого произвольного числа

Reading time2 min
Views23K
Как-то раз мне понадобилось написать генерацию суммы прописью для одного проекта. Поиск готовых решений ни к чему не привел, в результате родился маленький С++ класс, генерирующий прописной эквивалент числа. В качестве приятного бонуса я добавил туда поддержу рублей и долларов (это требовалось для того проекта). Под катом немного теории и ссылка на Git-репозиторий.

Теория

Названия чисел

В русском языке числа от 1 до 9 (так называемые единицы) и от 10 до 20 (второй ряд единиц) имеют индивидуальные названия. После 20 индивидуальные названия имеют десятки, а число образуется путем прибавления к названию десятки числа категории из категории единиц.

Пример:
  • 5 — пять
  • 17 — семнадцать
  • 23 — двадцать три
  • 48 — сорок восемь


Сотни включают в себя десятки и единицы, а тысячи содержат в себе все вышеперечисленные названия. И так по мере нарастания порядка числа, то есть каждый новый порядок включает в себя все предыдущие.

Женский и мужской род названий порядков

Тут есть следующая особенность. При формировании числа меньше 100 проблем нет, но при формировании прописного эквивалента больших сумм у вас появляются слова, обозначающие порядки сотен, десятов и единиц, а именно тысячи, миллионы и т.д.

Возникают такие варианты чисел:
  • одна тысяча
  • один миллион
  • два миллиона
  • две тысячи
  • пять тысяч

и т.п.

Правила такие:
  1. Для названий порядков женского рода приходится модифицировать 1 и 2 (одна, две);
  2. Для обоих родов по-разному склоняются окончания названий порядков для числа 1, группы от 2 до 4 и далее до 20 (включая второй ряд единиц от 11 до 19).


Пример:
  • 1 (одна) тысяча
  • 2-3-4 тысячи
  • 5-19 тысяч

  • 1 миллион
  • 2-3-4 миллиона
  • 5-20 миллионов


Зная эти особенности, мжно составить логику работы генератора прописного числа.

Класс

Механизм генерации числа работает следующим образом:

  1. Получив на входе число, определяем разряд числа (миллионы, тысячи или меньше);
  2. Для каждого порядка кроме генерируем сотни, десятки и единицы, дописывая в конце название порядка.


Так и родился C++ класс Propis. Из double значения на выходе получается строка с прописным значением и валютой числа (при наличии) с точностью до сотых. Реализована генерация чисел до 1 миллиарда, при необходимости можно легко сделать поддержку миллиардов и выше. Зависит только от стандартной библиотеки cmath и std::string.

Пример использования в C++ коде:
Propis *propis = new Propis;
double value = 345.12;

// Задаем число для генерации и тип валюты
std::string resultString = propis->conv(value, Propis::Dollar);
// "триста сорок пять долларов, двенадцать центов"


Пример использования в iOS-программе:
- (IBAction)valueChanged:(UITextField *)sender
{
    Propis propis;
    double value = [sender.text doubleValue];
    
    std::string stdResultString = propis.conv(value, Propis::NoCurrency);
    
    NSString *resultString = [NSString stringWithUTF8String:stdResultString.c_str()];
    
    self.resultView.text = resultString;
}


Git-репозиторий с исходным кодом класса находится здесь. Буду рад если кому-то пригодится.
Tags:
Hubs:
+1
Comments9

Articles