Слава Україні!
Преобразование числа в текст на php
1. Функция
/**
* Возвращает сумму прописью
* @uses morph(...)
*/
public function num2str($num) {
$nul='ноль';
$ten=array(
array('','один','два','три','четыре','пять','шесть','семь', 'восемь','девять'),
array('','одна','две','три','четыре','пять','шесть','семь', 'восемь','девять'),
);
$a20 = array('десять','одиннадцать','двенадцать','тринадцать','четырнадцать','пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать');
$tens = array(2=>'двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят' ,'восемьдесят','девяносто');
$hundred=array('','сто','двести','триста','четыреста','пятьсот','шестьсот', 'семьсот','восемьсот','девятьсот');
$unit = array( // Units
array('копейка' ,'копейки' ,'копеек' ,1),
array('рубль' ,'рубля' ,'рублей' ,0),
array('тысяча' ,'тысячи' ,'тысяч' ,1),
array('миллион' ,'миллиона','миллионов' ,0),
array('миллиард','милиарда','миллиардов',0),
);
//
list($rub,$kop) = explode('.', sprintf("%015.2f", floatval($num)));
$out = array();
if (intval($rub)>0) {
foreach(str_split($rub,3) as $uk=>$v) { // by 3 symbols
if (!intval($v)) continue;
$uk = sizeof($unit)-$uk-1; // unit key
$gender = $unit[$uk][3];
list($i1,$i2,$i3) = array_map('intval',str_split($v,1));
// mega-logic
$out[] = $hundred[$i1]; # 1xx-9xx
if ($i2>1) $out[]= $tens[$i2].' '.$ten[$gender][$i3]; # 20-99
else $out[]= $i2>0 ? $a20[$i3] : $ten[$gender][$i3]; # 10-19 | 1-9
// units without rub & kop
if ($uk>1) $out[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
} //foreach
}
else $out[] = $nul;
$out[] = morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
$out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
}
/**
* Склоняем словоформу
*/
public function morph($n, $f1, $f2, $f5) {
$n = abs(intval($n)) % 100;
if ($n>10 && $n<20) return $f5;
$n = $n % 10;
if ($n>1 && $n<5) return $f2;
if ($n==1) return $f1;
return $f5;
}
Пример использования:
num2str(878867.15); // восемьсот семьдесят восемь тысяч восемьсот шестьдесят семь рублей 15 копеек
2. Класс
class NumToText {
var $Mant = array(); // описания мантисс
// к примеру ('рубль', 'рубля', 'рублей')
// или ('метр', 'метра', 'метров')
var $Expon = array(); // описания экспонент
// к примеру ('копейка', 'копейки', 'копеек')
function Num2Text(){
}
// установка описания мантисс
function SetMant($mant){
$this->Mant = $mant;
}
/**
* установка описания экспонент
*/
function SetExpon($expon){
$this->Expon = $expon;
}
/** функция возвращает необходимый индекс описаний разряда
* ('миллион', 'миллиона', 'миллионов') для числа $ins
* например для 29 вернется 2 (миллионов)
* $ins максимум два числа
* @param $ins integer
* @return int
*/
function DescrIdx($ins){
if(intval($ins/10) == 1) // числа 10 - 19: 10 миллионов, 17 миллионов
return 2;
else {
// для остальных десятков возьмем единицу
$tmp = $ins%10;
if($tmp == 1) // 1: 21 миллион, 1 миллион
return 0;
else if($tmp >= 2 && $tmp <= 4)
return 1; // 2-4: 62 миллиона
else
return 2; // 5-9 48 миллионов
}
}
// IN: $in - число,
// $raz - разряд числа - 1, 1000, 1000000 и т.д.
// внутри функции число $in меняется
// $ar_descr - массив описаний разряда ('миллион', 'миллиона', 'миллионов') и т.д.
// $fem - признак женского рода разряда числа (true для тысячи)
function DescrSot(&$in, $raz, $ar_descr, $fem = false){
$ret = '';
$conv = intval($in / $raz);
$in %= $raz;
$descr = $ar_descr[ $this->DescrIdx($conv%100) ];
if($conv >= 100){
$Sot = array('сто', 'двести', 'триста', 'четыреста', 'пятьсот',
'шестьсот', 'семьсот', 'восемьсот', 'девятьсот');
$ret = $Sot[intval($conv/100) - 1] . ' ';
$conv %= 100;
}
if($conv >= 10){
$i = intval($conv / 10);
if($i == 1){
$DesEd = array('десять', 'одиннадцать', 'двенадцать', 'тринадцать',
'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать',
'восемнадцать', 'девятнадцать' );
$ret .= $DesEd[ $conv - 10 ] . ' ';
$ret .= $descr;
// возвращаемся здесь
return $ret;
}
$Des = array('двадцать', 'тридцать', 'сорок', 'пятьдесят', 'шестьдесят',
'семьдесят', 'восемьдесят', 'девяносто' );
$ret .= $Des[$i - 2] . ' ';
}
$i = $conv % 10;
if($i > 0){
if( $fem && ($i==1 || $i==2) ){
// для женского рода (сто одна тысяча)
$Ed = array('одна', 'две');
$ret .= $Ed[$i - 1] . ' ';
} else {
$Ed = array('один', 'два', 'три', 'четыре', 'пять',
'шесть', 'семь', 'восемь', 'девять' );
$ret .= $Ed[$i - 1] . ' ';
}
}
$ret .= $descr;
return $ret;
}
// IN: $sum - число, например 1256.18
function Convert($sum){
$ret = '';
// имена данных перменных остались от предыдущей версии
// когда скрипт конвертировал только денежные суммы
$Kop = 0;
$Rub = 0;
$sum = trim($sum);
// удалим пробелы внутри числа
$sum = str_replace(' ', '', $sum);
// флаг отрицательного числа
$sign = false;
if($sum[0] == '-'){
$sum = substr($sum, 1);
$sign = true;
}
// заменим запятую на точку, если она есть
$sum = str_replace(',', '.', $sum);
$Rub = intval($sum);
$Kop = $sum*100 - $Rub*100;
if($Rub){
// значение $Rub изменяется внутри функции DescrSot
// новое значение: $Rub %= 1000000000 для миллиарда
if($Rub >= 1000000000)
$ret .= $this->DescrSot($Rub, 1000000000, array('миллиард', 'миллиарда', 'миллиардов')) . ' ';
if($Rub >= 1000000)
$ret .= $this->DescrSot($Rub, 1000000, array('миллион', 'миллиона', 'миллионов') ) . ' ';
if($Rub >= 1000)
$ret .= $this->DescrSot($Rub, 1000, array('тысяча', 'тысячи', 'тысяч'), true) . ' ';
$ret .= $this->DescrSot($Rub, 1, $this->Mant) . ' ';
// если необходимо поднимем регистр первой буквы
$ret[0] = chr( ord($ret[0]) + ord('A') - ord('a') );
// для корректно локализованных систем можно закрыть верхнюю строку
// и раскомментировать следующую (для легкости сопровождения)
// $ret[0] = strtoupper($ret[0]);
}
if($Kop < 10)
$ret .= '0';
$ret .= $Kop . ' ' . $this->Expon[ $this->DescrIdx($Kop) ];
// если число было отрицательным добавим минус
if($sign)
$ret = '-' . $ret;
return $ret;
}
}
Использование:
$mt = new NumToText();
$mt->SetMant( array('рубль', 'рубля', 'рублей') );
$mt->SetExpon( array('копейка', 'копейки', 'копеек') );
echo $mt->Convert($HTTP_POST_VARS['num']);
Важлива інформація
Міністерство оборони
України
України
з 24.02 по 11.11
втрати противника
орієнтовно склали:
втрати противника
орієнтовно склали:
710660 ( +1770 )
особового складу
9253 ( +4 )
танків
18766 ( +40 )
бойових бронемашин
20314 ( +34 )
артилерійських систем
1245 ( +0 )
РСЗВ
996 ( +0 )
засоби ППО
369 ( +0 )
літаків
329 ( +0 )
гелікоптерів
28802 ( +119 )
автомобільної техніки
28 ( +0 )
кораблі / катери
2636 ( +2 )
крилаті ракети
18676 ( +57 )
БПЛА
3620 ( +16 )
спец. техніки
4 ( +0 )
установок ОТРК/ТРК
1 ( +0 )
підводні човни