/**
  * Return number converted to words
  *
  * @param Number $number
  *
  * @return string
  */
 public function toWords(Number $number)
 {
     $value = $number->getValue();
     if ($value === 0.0) {
         return NumberDictionary::$zero;
     }
     $triplets = [];
     while ($value > 0) {
         $triplets[] = $value % 1000;
         $value = (int) ($value / 1000);
     }
     $words = [];
     foreach ($triplets as $i => $triplet) {
         if ($triplet > 0) {
             $threeDigitsWords = $this->threeDigitsToWords($triplet);
             if ($i > 0) {
                 $case = $this->grammarCaseSelector->getGrammarCase($triplet);
                 $mega = NumberDictionary::$mega[$i][$case];
                 $threeDigitsWords = $threeDigitsWords . ' ' . $mega;
             }
             $words[] = $threeDigitsWords;
         }
     }
     return implode(' ', array_reverse($words));
 }
 /**
  * Converts the provided number into an array of number triplets
  * starting at the lowest (i.e. 123456789 => [789, 456, 123])
  *
  * @param Number $number
  *
  * @return array
  */
 protected function buildTriplets(Number $number)
 {
     $triplets = [];
     $value = $number->getValue();
     while ($value > 0) {
         $triplets[] = $value % 1000;
         $value = (int) ($value / 1000);
     }
     return $triplets;
 }
 /**
  * Determines if the provided number is singular
  *
  * @param Number $number
  *
  * @return bool
  */
 protected function isSingular(Number $number)
 {
     return $number->getValue() == 1;
 }
 /**
  * Converts a number to its word representation in Romanian
  *
  * Romanian uses a complex set of rules for numerals, and a lot of inflections are
  * interdependent. As such, this class implements an easy means for authors to
  * count either abstract numbers (in which case the second parameter should be
  * omitted), or actual nouns. In the latter case, a noun must be provided as an
  * indexed array containing three values:
  * 0 => the singular form
  * 1 => the plural form
  * 2 => the noun's gender, as one of the following constants:
  *      - Gender::MALE for masculine nouns
  *      - Gender::FEMALE for feminine nouns
  *      - Gender::NEUTER for neuter nouns
  *
  * @param Number $number An integer (or its string representation) between 9.99*-10^302
  *                        and 9.99*10^302 (999 centillions) that need to be converted to words
  * @param array $noun  Optionally you can also provide a noun to be formatted accordingly
  * @return string  The corresponding word representation
  * @access protected
  * @author Bogdan Stăncescu <*****@*****.**>
  */
 public function toWords(Number $number, $noun = array())
 {
     $num = $number->getValue();
     if (empty($noun)) {
         $noun = array(NULL, NULL, Gender::FEATURELESS);
     }
     $ret = '';
     // check if $num is a valid non-zero number
     if (!$num || preg_match('/^-?0+$/', $num) || !preg_match('/^-?\\d+$/', $num)) {
         $ret = NumberDictionary::getNumbers()[0];
         if ($noun[2] != Gender::FEATURELESS) {
             $ret .= $this->_sep . $this->_get_noun_declension_for_number('f', $noun);
         }
         return $ret;
     }
     // add a minus sign
     if (substr($num, 0, 1) == '-') {
         $ret = $this->_minus . $this->_sep;
         $num = substr($num, 1);
     }
     // One is a special case
     if (abs($num) == 1) {
         $ret = $this->_get_number_inflection_for_gender(NumberDictionary::getNumbers()[1], $noun);
         if ($noun[2] != Gender::FEATURELESS) {
             $ret .= $this->_sep . $this->_get_noun_declension_for_number('o', $noun);
         }
         return $ret;
     }
     // if the absolute value is greater than 9.99*10^302, return infinity
     if (strlen($num) > 306) {
         return $ret . $this->_infinity;
     }
     // strip excessive zero signs
     $num = ltrim($num, '0');
     // split $num to groups of three-digit numbers
     $num_groups = $this->_splitNumber($num);
     $sizeof_numgroups = count($num_groups);
     $showed_noun = false;
     foreach ($num_groups as $i => $number) {
         // what is the corresponding exponent for the current group
         $pow = $sizeof_numgroups - $i;
         $valid_groups = array();
         // skip processment for empty groups
         if ($number == '000') {
             continue;
         }
         if ($i) {
             $ret .= $this->_sep;
         }
         if ($pow - 1) {
             $ret .= $this->_showDigitsGroup($number, NumberDictionary::getExponents()[($pow - 1) * 3]);
         } else {
             $showed_noun = true;
             $ret .= $this->_showDigitsGroup($number, $noun, false, $num != 1);
         }
     }
     if (!$showed_noun) {
         $ret .= $this->_sep . $this->_get_noun_declension_for_number('m', $noun);
         // ALWAYS many
     }
     return rtrim($ret, $this->_sep);
 }