Jump to content
php.lv forumi

Ciparai par burtiem!


imop

Recommended Posts

Sveika tauta!

 

Man maza problēma ar cipariem un LV locījumiem pie skaitļu izvades ar vārdiem.

 

 

piem_1. ja summa ir 11.21

 

man izvadās: vienpadsmit Lati, 21 santīms

 

piem_2. ja summa ir 10.20

 

man izvadās: desmit Lats, 20 santīms

 

 

Tā pati problēma ir ar gan latiem, gan santīmiem - 0 / 10 / 20 / 40 / utt. Latiem izvadās kā piem. četrdesmit Lats, 00 santīms

 

šeit ir kods:

 

public function GetCurrency($int, $major = 'lats', $minor = 'santims')
   {
       if (strpos($int, '.') !== false) {
           $left  = substr($int, 0, strpos($int, '.'));
           $right = substr($int, strpos($int, '.') + 1);

           // Mainīgais pirms punkta $major ?
           if (substr($left,1,strlen($left)) <= 1) {
               $major = 'lats'; 
           } else {
               $major = 'lati';
           }


           // Mainīgais pēc punkta $minor ?
           if (substr($right,1,strlen($right)) <= 1) {
               $minor = 'santīms';

           } else {
               $minor = 'santīmi';
           }

       //  $text  = self::GetText($left) . " $major and " . self::GetText($right) . " $minor"; // Cena ar cipars Lats, cipars santīms
		$text  = self::GetText($left) . " $major, " . $right . " $minor"; // Cena ar cipars Lats, 31 santims

       } else {
           $text = self::GetText($int) . " $major";
       }

       return $text;
   }

 

 

zinu ka kodam vajadzēti izskatīties apmērm šādam:

 

// Mainīgais pirms punkta $major ?
            if (substr($left,1,strlen($left)) <= 1) {
               $major = 'lats';
			} elseif (substr($left,2,strlen($left)) == 10) {
			$major = 'lati';
           } else {
               $major = 'lati';
           }

 

bet man neizdodās to panākt, vai arī kods ignorē to skaitli

 

Help...

Edited by imop
Link to comment
Share on other sites

function cur($s){
 list($ma,$mi)=explode('.',$s);
 return $ma.' lat'.((int)$ma%10==1?'s':'i').' '.$mi.' santīm'.((int)$mi%10==1?'s':'i');
}

echo cur('20.41').'<br />';
echo cur('22.43').'<br />';
echo cur('24.45').'<br />';
echo cur('26.47').'<br />';
echo cur('28.49').'<br />';
echo cur('25.50').'<br />';

Link to comment
Share on other sites

Tie varianti tika izmēģināti un neviens īsti nestrādā, ja

 

skaitlis ir: 101.90

 

tad man jāizvada - viens simts viens lats, 90 santīmi

patreiz ir - viens simts viens lats, 90 santims

 

ja skaitlis ir 101.91

 

tad jāizvada - viens simts viens lats, 91 santīms

patreiz ir - viens simts viens lati, 90 santīmi

 

 

ja skaitlis ir 80.10

 

tad jāizvada - astoņdesmit lati, 10 santīmi

patreiz ir - astoņdesmit lats, 10 santims

 

utt. vajadzētu lai skripts atšķir kad ir desmiti / simti / tulkstoši - man nekādigi nesanāk

 

Šeit viss skripts:

 

<?php
   /**
   * o------------------------------------------------------------------------------o
   * | This package is licensed under the Phpguru license. A quick summary is       |
   * | that for commercial use, there is a small one-time licensing fee to pay. For |
   * | registered charities and educational institutes there is a reduced license   |
   * | fee available. You can read more  at:                                        |
   * |                                                                              |
   * |                  http://www.phpguru.org/static/license.html                  |
   * o------------------------------------------------------------------------------o
   *
   */


/**
* Converts a given number to a textual representation of it
*/
class TextualNumber
{
private static $units  = array(NR_0, NR_1, NR_2, NR_3, NR_4, NR_5, NR_6, NR_7, NR_8, NR_9);
   private static $teens  = array(NR_10, NR_11, NR_12, NR_13, NR_14, NR_15, NR_16, NR_17, NR_18, NR_19);
   private static $tens   = array(2 => NR_20, NR_30, NR_40, NR_50, NR_60, NR_70, NR_80, NR_90);
   private static $suffix = array(NR_1000, NR_MILL, NR_BILL, NR_TILL, NR_QUAD);

   /**
   * Returns appropriate text for given number. Despite
   * appearances the number should (though isn't required) be 
   * passed in as a string. This allows large numbers to be
   * converted. Integers are handled just fine though.
   * Negative numbers are handled fine.
   * 
   * The billion/trillion etc suffixes are done using the American
   * style (eg 9 zeros for billion, 12 for trillion), which albeit
   * being mathmetically incorrect, is (I believe) the commonly
   * accepted norm. Since this code was written for the purpose
   * of validating human vs spider form submissions, this is the
   * more appropriate way to go.
   * 
   * @param  string $int The number to convert. Optional.
   * @return text        Resulting text
   */
   private static function ToString($int)
   {
       // Check for purely numeric chars
       if (!preg_match('#^[\d.]+$#', $int)) {
           throw new Exception('Invalid characters in input');
       }

       // Handle decimals
       if (strpos($int, '.') !== false) {
           $decimal = substr($int, strpos($int, '.') + 1);
           $int     = substr($int, 0, strpos($int, '.'));
       }

       // Lose insignificant zeros
       $int = ltrim($int, '0');

       // Check for valid number
       if ($int == '') {
           $int = '0';
       }


       // Lose the negative, don't use abs() so as to allow large numbers
       if ($negative = ($int < 0)) {
           $int = substr($int, 1);
       }

       // Number too big?
       if (strlen($int) > 18) {
           throw new Exception('Out of range');
       }

       // Keep original number
       $orig = $int;

       /**
       * Main number deciphering bit thing
       */
       switch (strlen($int)) {

           // Single digit number
           case '1':
               $text = self::$units[$int];
               break;


           // Two digit number
           case '2':
               if ($int{0} == '1') {
                   $text = self::$teens[$int{1}];

               } else if ($int{1} == '0') {
                   $text = self::$tens[$int{0}];

               } else {
                   $text = self::$tens[$int{0}] . ' ' . self::$units[$int{1}];
               }
               break;


           // Three digit number
           case '3':
               if ($int % 100 == 0) {
                   $text = self::$units[$int{0}] . ' simts';
               } else {
                   $text = self::$units[$int{0}] . ' simts ' . self::GetText(substr($int, 1));
               }
               break;


           // Anything else
           default:
               $pieces      = array();
               $suffixIndex = 0;

               // Handle the last three digits
               $num = substr($int, -3);
               if ($num > 0) {
                   $pieces[] = self::GetText($num);
               }
               $int = substr($int, 0, -3);

               // Now handle the thousands/millions etc
               while (strlen($int) > 3) {
                   $num   = substr($int, -3);

                   if ($num > 0) {
                       $pieces[] = self::GetText($num) . ' ' . self::$suffix[$suffixIndex];
                   }
                   $int = substr($int, 0, -3);
                   $suffixIndex++;
               }

               $pieces[] = self::GetText(substr($int, -3)) . ' ' . self::$suffix[$suffixIndex];

               /**
               * Figure out whether we need to add "and" in there somewhere
               */
               $pieces = array_reverse($pieces);

               if (count($pieces) > 1 AND strpos($pieces[count($pieces) - 1], ' and ') === false) {
                   $pieces[] = $pieces[count($pieces) - 1];
                   $pieces[count($pieces) - 2] = 'and';
               }

               // Create the text
               $text = implode(' ', $pieces);

               // Negative number?
               if ($negative) {
                   $text = 'minus ' . $text;
               }
               break;
       }

       /**
       * Handle any decimal part
       */
       if (!empty($decimal)) {
           $pieces  = array();
           $decimal = preg_replace('#[^0-9]#', '', $decimal);

           for ($i=0, $len=strlen($decimal); $i<$len; ++$i) {
               $pieces[] = self::$units[$decimal{$i}];
           }

           $text .= ' point ' . implode(' ', $pieces);
       }


       return $text;
   }


   /**
   * Returns text for given number. Parameter should ideally
   * be a string (to handle large numbers) though integers are
   * OK.
   * 
   * @param  string $int Number to convert
   * @return string      Resulting textual representation
   */
   public function GetText($int)
   {
       return self::ToString($int);
   }


   /**
   * Returns text and number for a randomly generated number.
   * 
   * @return array Array of number and textual representation
   */
   public function Get()
   {
       $int = mt_rand();
       return array($int, self::ToString($int));
   }


   /**
   * Returns currency version of a given number.
   * 
   * @param  string $int   Number to convert
   * @param  string $major Word to use for left hand side of decimal point
   * @param  string $minor Word to use for right hand side of decimal point
   * @return string        Resulting string
   */
    public function GetCurrency($int, $major = 'lats', $minor = 'santims')
   {
       if (strpos($int, '.') !== false) {
           $left  = substr($int, 0, strpos($int, '.'));
           $right = substr($int, strpos($int, '.') + 1);

           // Mainīgais pirms punkta ?
           if (substr($left,1,strlen($left)) <= 1) {
               $major = 'lats'; 
           } else {
               $major = 'lati';
           }


           // Mainīgais pēc punkta ?
           if (substr($right,1,strlen($right)) <= 1) {
               $minor = 'santīms';
			} elseif (substr($right,0,strlen($right)) == 90) {
			$minor = 'santīmi';
           } else {
               $minor = 'santīmi';
           }

       //  $text  = self::GetText($left) . " $major and " . self::GetText($right) . " $minor"; // Cena ar cipars Lats, cipars santīms
		$text  = self::GetText($left) . " $major, " . $right . " $minor"; // Cena ar cipars Lats, 31 santims

       } else {
           $text = self::GetText($int) . " $major";
       }

       return $text;
   }
}
?> 

Link to comment
Share on other sites

Nezinu, kur dabīji funkciju, bet katrai valodai sava specifika, nederēs tev tāda, kas paredzēta angļu valodai...

 

Varbūt paprovē pats palauzīt galvu, un izštukot? :)

 

(vispār, biju ievietojis topikā "Noderīgas funkcijas" funkciju, kas konvertē uz LV summu vārdiem (lai gan viņa nestrādā ar simtiem, ko nāksies pašam piemeistarot klāt)

Link to comment
Share on other sites

Nezinu, kur dabīji funkciju, bet katrai valodai sava specifika, nederēs tev tāda, kas paredzēta angļu valodai...

 

Varbūt paprovē pats palauzīt galvu, un izštukot? :)

 

(vispār, biju ievietojis topikā "Noderīgas funkcijas" funkciju, kas konvertē uz LV summu vārdiem (lai gan viņa nestrādā ar simtiem, ko nāksies pašam piemeistarot klāt)

 

patiesībā jau ir tā ka man tā funkcijas ir gaužām svešas, tapēc jau vēršos šeit pēc padoma un vēlēdot kādas mazliet reālākas atbildes. Piemēram kur paskatāities, palasīt info kā šādas sakarības var izveidot!

 

Veidoju ko tādu pirmo reizi!

Link to comment
Share on other sites

Principā, vajag tik mācēt sadalīt skaitli pa cipariem un sarakstīt prātīgus if'us.

Tas, cik funkcija būs "efektīva", atkarīgs no saprašanas līmeņa :)

 

Rekur manis rakstītā:

http://php.lv/f/topic/15423-noderigas-funkcijas/page__p__118589entry118589

 

Nav varbūt efektīvākais veids, ir arī daži trūkumi (ierobežojumi), bet strādā...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...