Jump to content
php.lv forumi

Skaitļu pārveidotājs par tekstu


GedroX

Recommended Posts

Tātad, dažreiz vajag arī lielākus skaitļus, līdz ar to, papildināju funkciju, t.s. noņēmu arī tos liekos (int) un abs(), jo tie ierobežo skaitļus līdz int maksimumam.

 

Tagad max skaitlis, ko šī funkcija māk uzrakstīt ir "999999999999999999999999999999999999999999999999999999999999999" -> skaitlis ar 63 cipariem. (bez decimāldaļām)

 

Uzrakstot šo skaitli, sanāk šāds te teksts:

number2string:

 

deviņi simti deviņdesmit deviņi nondeciljoni deviņi simti deviņdesmit deviņi oktdeciljoni deviņi simti deviņdesmit deviņi septdeciljoni deviņi simti deviņdesmit deviņi seksdeciljoni deviņi simti deviņdesmit deviņi kvintdeciljoni deviņi simti deviņdesmit deviņi kvartdeciljoni deviņi simti deviņdesmit deviņi trideciljoni deviņi simti deviņdesmit deviņi duodeciljoni deviņi simti deviņdesmit deviņi undeciljoni deviņi simti deviņdesmit deviņi deciljoni deviņi simti deviņdesmit deviņi nontiljoni deviņi simti deviņdesmit deviņi oktiljoni deviņi simti deviņdesmit deviņi septiljoni deviņi simti deviņdesmit deviņi sekstiljoni deviņi simti deviņdesmit deviņi kvintiljoni deviņi simti deviņdesmit deviņi kvadriljoni deviņi simti deviņdesmit deviņi triljoni deviņi simti deviņdesmit deviņi miljardi deviņi simti deviņdesmit deviņi miljoni deviņi simti deviņdesmit deviņi tūkstoši deviņi simti deviņdesmit deviņi

 

 

if (!function_exists('number2string'))
{
  function number2string($n)
  {
     //$n = (int)$n;
     if ($n < 0) $b = 'mīnus ';
     //$n = abs($n);
     if ($n == '0')
     {
        return 'nulle';
     }
     else
     {
        return $b . _number2stringBig($n);
     }
  }
}

if (!function_exists('_number2stringBig'))
{
  function _number2stringBig($n)
  {
     if ($n == '0') return;
     $e = Array(
        Array(
           '1' => 'tūkstotis',
           '2' => 'miljons',
           '3' => 'miljards',
           '4' => 'triljons',
           '5' => 'kvadriljons',
           '6' => 'kvintiljons',
           '7' => 'sekstiljons',
           '8' => 'septiljons',
           '9' => 'oktiljons',
           '10' => 'nontiljons',
           '11' => 'deciljons',
           '12' => 'undeciljons',
           '13' => 'duodeciljons',
           '14' => 'trideciljons',
           '15' => 'kvartdeciljons',
           '16' => 'kvintdeciljons',
           '17' => 'seksdeciljons',
           '18' => 'septdeciljons',
           '19' => 'oktdeciljons',
           '20' => 'nondeciljons',
        ),
        Array(
           '1' => 'tūkstoši',
           '2' => 'miljoni',
           '3' => 'miljardi',
           '4' => 'triljoni',
           '5' => 'kvadriljoni',
           '6' => 'kvintiljoni',
           '7' => 'sekstiljoni',
           '8' => 'septiljoni',
           '9' => 'oktiljoni',
           '10' => 'nontiljoni',
           '11' => 'deciljoni',
           '12' => 'undeciljoni',
           '13' => 'duodeciljoni',
           '14' => 'trideciljoni',
           '15' => 'kvartdeciljoni',
           '16' => 'kvintdeciljoni',
           '17' => 'seksdeciljoni',
           '18' => 'septdeciljoni',
           '19' => 'oktdeciljoni',
           '20' => 'nondeciljoni',
        ),
     );
     //$n = (string)abs($n);
     $length = strlen((string)$n);
     $pow = ceil($length / 3) - 1;
     $digits = ($length - 1) % 3 + 1;

     $begin = substr($n, 0, $digits);
     $s = _number2stringSmall($begin);
     if ($pow > 0)
     {
        $end = substr($n, $digits);
        if (substr($begin, -1) == 1 && substr($begin, 0, 1) == 1)
        {
           $middle = $e[0][$pow];
        }
        else
        {
           $middle = $e[1][$pow];
        }
        $s .= ' ' . $middle;
        $s .= ' ' . _number2stringBig($end);
     }

     return $s;
  }
}

if (!function_exists('_number2stringSmall'))
{
  function _number2stringSmall($n)
  {
     $digits = Array('', 'viens', 'divi', 'trīs', 'četri', 'pieci', 'seši', 'septiņi', 'astoņi', 'deviņi');
     $preDigits = Array('', 'vien', 'div', 'trīs', 'četr', 'piec', 'seš', 'septiņ', 'astoņ', 'deviņ');
     $n = (string)$n;
     $l = strlen($n);
     if ($l > 3) return false;
     if ($l == 3)
     {
        return ($n{0} == 1 ? (substr($n, 1) == '00' ? 'simts' : 'viens simts') : $digits[$n{0}] . ' ' . 'simti') . ' ' . _number2stringSmall(substr($n, 1));
     }
     else
     {
        if ($l == 1) return $digits[$n];
        if ($n{0} == 1)
        {
           if ($n == '10') return 'desmit';
           return $preDigits[$n{1}] . 'padsmit';
        }
        $s = $preDigits[$n{0}] . 'desmit';
        if ($n{1} != '0')
        {
           $s .= ' ' . $digits[$n{1}];
        }
        return $s;
     }
  }
}

 

Ceru, ka noderēs ;)

 

p.s. iespējams, ka pirms likšanas funkcijā vajag nedaudz validācijas, jo ir noņemti tie abs() utt. kas bija sākumā ;)

Link to comment
Share on other sites

Un ja gribam lielisku funkciju, kas latviešu valodā pārvērš skaitļus par summu vārdos, tad pie esošajām funkcijām pievienojam vēl trīs funkcijas, un šeit gatavais rezultāts (apvienoju speciāli priekš ātrajiem copy & paste variantiem):

 

 


if (!function_exists('number2string'))
{
  function number2string($n)
  {
     //$n = (int)$n;
     if ($n < 0) $b = 'mīnus ';
     //$n = abs($n);
     if ($n == '0')
     {
        return 'nulle';
     }
     else
     {
        return $b . _number2stringBig($n);
     }
  }
}

if (!function_exists('_number2stringBig'))
{
  function _number2stringBig($n)
  {
     if ($n == '0') return;
     $e = Array(
        Array(
           '1' => 'tūkstotis',
           '2' => 'miljons',
           '3' => 'miljards',
           '4' => 'triljons',
           '5' => 'kvadriljons',
           '6' => 'kvintiljons',
           '7' => 'sekstiljons',
           '8' => 'septiljons',
           '9' => 'oktiljons',
           '10' => 'nontiljons',
           '11' => 'deciljons',
           '12' => 'undeciljons',
           '13' => 'duodeciljons',
           '14' => 'trideciljons',
           '15' => 'kvartdeciljons',
           '16' => 'kvintdeciljons',
           '17' => 'seksdeciljons',
           '18' => 'septdeciljons',
           '19' => 'oktdeciljons',
           '20' => 'nondeciljons',
        ),
        Array(
           '1' => 'tūkstoši',
           '2' => 'miljoni',
           '3' => 'miljardi',
           '4' => 'triljoni',
           '5' => 'kvadriljoni',
           '6' => 'kvintiljoni',
           '7' => 'sekstiljoni',
           '8' => 'septiljoni',
           '9' => 'oktiljoni',
           '10' => 'nontiljoni',
           '11' => 'deciljoni',
           '12' => 'undeciljoni',
           '13' => 'duodeciljoni',
           '14' => 'trideciljoni',
           '15' => 'kvartdeciljoni',
           '16' => 'kvintdeciljoni',
           '17' => 'seksdeciljoni',
           '18' => 'septdeciljoni',
           '19' => 'oktdeciljoni',
           '20' => 'nondeciljoni',
        ),
     );
     //$n = (string)abs($n);
     $length = strlen((string)$n);
     $pow = ceil($length / 3) - 1;
     $digits = ($length - 1) % 3 + 1;

     $begin = substr($n, 0, $digits);
     $s = _number2stringSmall($begin);
     if ($pow > 0)
     {
        $end = substr($n, $digits);
        if (substr($begin, -1) == 1 && substr($begin, 0, 1) == 1)
        {
           $middle = $e[0][$pow];
        }
        else
        {
           $middle = $e[1][$pow];
        }
        $s .= ' ' . $middle;
        $s .= ' ' . _number2stringBig($end);
     }

     return $s;
  }
}

if (!function_exists('_number2stringSmall'))
{
  function _number2stringSmall($n)
  {
     $digits = Array('', 'viens', 'divi', 'trīs', 'četri', 'pieci', 'seši', 'septiņi', 'astoņi', 'deviņi');
     $preDigits = Array('', 'vien', 'div', 'trīs', 'četr', 'piec', 'seš', 'septiņ', 'astoņ', 'deviņ');
     $n = (string)$n;
     $l = strlen($n);
     if ($l > 3) return false;
     if ($l == 3)
     {
        return $digits[$n{0}] . ($n{0} == 1 ? ' simts' : ' simti') . ' ' . _number2stringSmall(substr($n, 1));
     }
     else
     {
        if ($l == 1) return $digits[$n];
        if ($n{0} == 1)
        {
           if ($n == '10') return 'desmit';
           return $preDigits[$n{1}] . 'padsmit';
        }
        $s = $preDigits[$n{0}] . 'desmit';
        if ($n{1} != '0')
        {
           $s .= ' ' . $digits[$n{1}];
        }
        return $s;
     }
  }
}

function addBigCurrency($n)
{
  $last = substr($n, -1);
  if($last == 0)
  {
     return " latu";
  }
  elseif($last == 1)
  {
     return " lats";
  }
  else
  {
     return " lati";
  }
}

function addSmallCurrency($n)
{
  $last = substr($n, -1);
  if($last == 0)
  {
     return " santīmu";
  }
  elseif($last == 1)
  {
     return " santīms";
  }
  else
  {
     return " santīmi";
  }
}

function amount2words($num)
{
  if($num > 999999999999999999999999999999999999999999999999999999999999999.99)
  {
     return "ERROR: Skaitlis ir par lielu!";
  }
  elseif($num < -999999999999999999999999999999999999999999999999999999999999999.99)
  {
     return "ERROR: Skaitlis ir par mazu!";
  }
  else
  {
     //funkcija pieņem tikai skaitļus ar "." kā decimālattalītāju
     $parts = explode(".", $num);
     if(count($parts) <= 2)
     {
        $int = $parts[0];
        $dec = $parts[1];
        $str_resp = number2string($int).addBigCurrency($int);
        if(count($parts) == 2)
        {
           if($dec > 99 || $dec < 0)
           {
              return "ERROR: Unknown situation!";
           }
           elseif($dec > 0 || $dec < 10)
           {
              if(strlen($dec) > 1)
              {
                 $dec = intval($dec);
              }
              else
              {
                 $dec = $dec * 10;
              }
              $str_resp .= " un ".$dec.addSmallCurrency($dec);
           }
           else
           {
              $str_resp .= " un ".$dec.addSmallCurrency($dec);
           }
        } //RG: ja nepieciešams izvadīt arī 00 santīmus, kad tie nav pierakstīti! /*
        else
        {
           $str_resp .= " un 00".addSmallCurrency($dec);
        } //*/
        return $str_resp;
     }
     else
     {
        return "ERROR: Unknown situation!";
     }
  }
}

 

Piemērs:

 

echo "<br>number2string: ".amount2words(3456.99)."<br>";

//number2string: trīs tūkstoši četri simti piecdesmit seši lati un 99 santīmi

 

Ja nu kāds atrod vēl kādu kļūdu, vai ieteicamu uzlabojumu, tad droši, rakstam, ja varam, tad arī labojam.. un postojam iekšā :)

Edited by darksign
Link to comment
Share on other sites

p.s. atradu vēl vienu bagu, kur autors samudžinājies ifos bija, tad nu nomainīju arī iepriekšējam postam šo rindiņu:

 

        return ($n{0} == 1 ? (substr($n, 1) == '00' ? 'simts' : 'viens simts') : $digits[$n{0}] . ' ' . 'simti') . ' ' . _number2stringSmall(substr($n, 1));

 

pret šo:

        return $digits[$n{0}] . ($n{0} == 1 ? ' simts' : ' simti') . ' ' . _number2stringSmall(substr($n, 1));

 

Jo iepriekš bija kļūda, piemēram, ja summa ir 51010, tad uzrakstītais teksts ir "piecdesmit viens tūkstotis simti desmit latu", kaut gan vajadzētu "piecdesmit viens tūkstotis simts desmit latu".

 

Lūk arī vēl viens apstiprinājums kiss metodikai, ka jo vienkāršāk rakstam kodu, jo vienkāršāk pašam un citiem saprast ko mēs tur vispār daram... jo uz sākotnējo rindu man vismaz nav ērti skatīties.. kad tiek dubultoti ifi ar šo konkrēto speciālo sintaksi. Lai gan ērti izmantot, un dažreiz pat labi (nav jātaisa papildus mainīgie), bet tomēr, manuprāt, grūtāk salasīt un ātri ieraudzīt vienkāršas kļūdas.

Link to comment
Share on other sites

  • 8 months later...
  • 5 months later...

 	$n = (string)$n;

 

надо заменить на

 

 	$n = (string) intval($n); //здесь, если не сделать число целым, далее происходит ошибка из-за 0 впереди. Например, если $n="09";

Link to comment
Share on other sites

×
×
  • Create New...