Перевод чисел в слова

Нужен был перевод чисел в словесную форму. Попробовал разобраться с функцией AmountToStr в scr_ConvertUtils. Но понял, что проще заново написать, чем переделать ее из обработки денежных значений.
Врать не буду взял отсюда
http://algolist.manual.ru/maths/misc/sumwrite.php

function AmountToStrEx(Amount, Sex) {
        if (Sex == undefined) {
                var Sex = 0;
        }
        var Result = '';
        var Div = 1;
        var Str = '';
        var i = 0;
        var Thousands = [                   // род, один, несколько (2-4), много (>4)
                [0,''            ,''             ,''              ],
                [1,'тысяча '     ,'тысячи '      ,'тысяч '        ],
                [0,'миллион '    ,'миллиона '    ,'миллионов '    ],
                [0,'миллиард '   ,'миллиарда '   ,'миллиардов '   ],
                [0,'триллион '   ,'триллиона '   ,'триллионов '   ],
                [0,'квадриллион ','квадриллиона ','квадриллионов '],
                [0,'квинтиллион ','квинтиллиона ','квинтиллионов ']   // 6
        ]
        var ToHundreds = [                  // до 10[по родам], 10-19, 10-90, 100-900
                [[''       ,''       ,''],               'десять '      ,''            ,''          ],
                [['один '  ,'одна '  ,'одно '],      'одиннадцать ' ,'десять '     ,'сто '      ],
                [['два '   ,'две '   ,'два '],  'двенадцать '  ,'двадцать '   ,'двести '   ],
                [['три '   ,'три '   ,'три '],  'тринадцать '  ,'тридцать '   ,'триста '   ],
                [['четыре ','четыре ','четыре '],'четырнадцать ','сорок '      ,'четыреста '],
                [['пять '  ,'пять '  ,'пять '],      'пятнадцать '  ,'пятьдесят '  ,'пятьсот '  ],
                [['шесть ' ,'шесть ' ,'шесть '], 'шестнадцать ' ,'шестьдесят ' ,'шестьсот ' ],
                [['семь '  ,'семь '  ,'семь '],      'семнадцать '  ,'семьдесят '  ,'семьсот '  ],
                [['восемь ','восемь ','восемь '],'восемнадцать ','восемьдесят ','восемьсот '],
                [['девять ','девять ','девять '],'девятнадцать ','девяносто '  ,'девятьсот ']   // 10
        ]
       
        if (Amount == 0) return 'ноль ';
        if (Amount 0) {
                Result = 'минус ';
                Amount = -1 * Amount;
        }
        for(i = 0; Div = Amount; i++) Div *= 1000;
       
        for(i = i - 1; i >= 0; i--){
                Div = Math.pow(10, i*3);
                Many = Math.floor(Amount / Div);
                Amount %= Div;
                Str='';
                if (Many == 0){
                        if (i > 0) continue;
                        Str += Thousands[i][1];
                } else {
                        if(Many>=100){
                                Str += ToHundreds[Math.floor(Many/100)][3];
                                Many %= 100;
                        }
                        if(Many>=20){
                                Str += ToHundreds[Math.floor(Many/10)][2];
                                Many %= 10;
                        }
                        if(Many>=10) Str += ToHundreds[Many-10][1];
                        else
                        if(Many>=1) {
                                if (i == 0) {
                                        Str += ToHundreds[Many][0][Sex];
                                } else Str += ToHundreds[Many][0][Thousands[i][0]];
                        }
                        switch(Many){
                                case 1: Str += Thousands[i][1]; break;
                                case 2: case 3:
                                case 4: Str += Thousands[i][2]; break;
                                default: Str += Thousands[i][3]; break;
                        };
                }
                Result += Str;
        }
        return Result;
}

Нравится

Поделиться

3 комментария

К этой функции может заодно пригодиться и склонение слов по числу.

надо бы еще в начало вставить

	if (isNaN(Amount) || Amount.toString().length > 12) {
		ShowInformationDialog("Некорректное числовое значение");
		return;
	}

Update #1

function PluralForm (n, FormArray) {  // спасибо Александру Звереву
        if (n%100 > 10 && n%100 < 20) return FormArray[2];
        switch (n % 10) {
                case 1:return FormArray[0];
                case 2:
                case 3:
                case 4:return FormArray[1];
                default:return FormArray[2];
        }
}
 
function FloatToStrSF(Amount, Precision, NameInt, NameFract, SexInt, SexFract) {
	if (isNaN(Amount) || Amount.toString().length > 12) {
		ShowInformationDialog("Некорректное числовое значение");
		return;
	} else 
	if (IsZeroValue(Amount)) return 'ноль ' + NameInt + ' ноль ' + NameFract;
	if (Precision == undefined) Precision = 2;
	var AmountInt = Math.floor(Amount);
	Precision = Math.pow(10, Precision);
	var AmountFract = Math.round((Amount - Int) * Precision);
 
	/* если нужны проверки
	if (NameInt == undefined || IsEmptyValue(NameInt)) {
		var NameInt = PluralForm (AmountInt, ['целое', 'целых', 'целых']);
		var SexInt = 0;
	} else
	if (SexInt == undefined) var SexInt = 0;
	if (NameFract == undefined || IsEmptyValue(NameFract)) {
		if (!IsZeroValue(Precision)) {
			var NameFractArr = ['', 'десятых', 'сотых', 'тысячных', 'десятитысячных', 
								'сто-тысячных', 'миллионных']
			var NameFract = NameFractArr[Precision];
			NameFract = PluralForm (AmountFract, [NameFract.substr(0,NameFract.length-2) + 'ая', 
										NameFract, NameFract]);
		}
		var SexFract = 0;
	} else
	if (SexFract == undefined) var SexFract = 0; */
 
	var StrInt = AmountToStrSF(AmountInt, SexInt);
	var StrFract = AmountToStrSF(AmountFract, SexFract);
	return StrInt + ' ' + NameInt + ' ' + StrFract + ' ' + NameFract;
}
 
function AmountToStrSF(Amount, Sex) {
	if (Sex == undefined) {
		var Sex = 0;
	}
	var Result = '';
	var Div = 1;
	var Str = '';
	var i = 0;
	var Thousands = [                   // род, один, несколько (2-4), много (>4)
		[0,''            ,''             ,''              ],
		[1,'тысяча '     ,'тысячи '      ,'тысяч '        ],
		[0,'миллион '    ,'миллиона '    ,'миллионов '    ],
		[0,'миллиард '   ,'миллиарда '   ,'миллиардов '   ],
		[0,'триллион '   ,'триллиона '   ,'триллионов '   ],
		[0,'квадриллион ','квадриллиона ','квадриллионов '],
		[0,'квинтиллион ','квинтиллиона ','квинтиллионов ']   // 6
	]
	var ToHundreds = [                  // до 10[по родам], 10-19, 10-90, 100-900
		[[''       ,''       ,''],		 'десять '      ,''            ,''          ],
		[['один '  ,'одна '  ,'одно '],	 'одиннадцать ' ,'десять '     ,'сто '      ],
		[['два '   ,'две '   ,'два '],	 'двенадцать '  ,'двадцать '   ,'двести '   ],
		[['три '   ,'три '   ,'три '],	 'тринадцать '  ,'тридцать '   ,'триста '   ],
		[['четыре ','четыре ','четыре '],'четырнадцать ','сорок '      ,'четыреста '],
		[['пять '  ,'пять '  ,'пять '],	 'пятнадцать '  ,'пятьдесят '  ,'пятьсот '  ],
		[['шесть ' ,'шесть ' ,'шесть '], 'шестнадцать ' ,'шестьдесят ' ,'шестьсот ' ],
		[['семь '  ,'семь '  ,'семь '],	 'семнадцать '  ,'семьдесят '  ,'семьсот '  ],
		[['восемь ','восемь ','восемь '],'восемнадцать ','восемьдесят ','восемьсот '],
		[['девять ','девять ','девять '],'девятнадцать ','девяносто '  ,'девятьсот ']   // 10
	]
 
	if (Amount == 0) return 'ноль ';
	if (Amount < 0) {
		Result = 'минус ';
		Amount = -1 * Amount;
	}
	for(i = 0; Div <= Amount; i++) Div *= 1000;
 
	for(i = i - 1; i >= 0; i--){
		Div = Math.pow(10, i*3);
		Many = Math.floor(Amount / Div);
		Amount %= Div;
		Str='';
		if (Many == 0){
			if (i > 0) continue;
			Str += Thousands[i][1];
		} else {
			if(Many>=100){
				Str += ToHundreds[Math.floor(Many/100)][3];
				Many %= 100;
			} 
			if(Many>=20){
				Str += ToHundreds[Math.floor(Many/10)][2];
				Many %= 10;
			} 
			if(Many>=10) Str += ToHundreds[Many-10][1]; 
			else
			if(Many>=1) {
				if (i == 0) {
					Str += ToHundreds[Many][0][Sex];
				} else Str += ToHundreds[Many][0][Thousands[i][0]];
			}
			switch(Many){
				case 1: Str += Thousands[i][1]; break;
				case 2: case 3:
				case 4: Str += Thousands[i][2]; break;
				default: Str += Thousands[i][3]; break;
			};
		}
		Result += Str;
	}
	return Result.substr(0,Result.length-1);
}
Показать все комментарии