/** * 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); }