/** * Число прописью * @version 1.0 beta * * @param int $num * @param int $numeral_type Тип числительного: 1 - количественное, 2 - порядковое * @param int $case Падеж: 1 - именительный, 2 - родительный, 3 - дательный, 4 - винительный, 5 - творительный, 6 - предложный * @param int $gender Пол: 1 - мужской, 2 - женский * @param int $subject_type 1 - неодушевленный, 2 - одушевленный * @param array $noun таблица со спряжениями сопутствующего существительного */ public static function numtostr($num, $numeral_type = 1, $case = 1, $gender = 1, $subject_type = 1, $noun = NULL) { $nouns = self::$LIBTEXT_GLOBALS['nouns']; $str = array(); if (bccomp('1000000000000', $num) != 1 || bccomp($num, '0') != 1) { return false; } // sum must be from 0 to 1 000 000 000 000 if (bccomp($num, '0') == 0) { } // TODO: special case, sum is equal to zero // Fetch triplets one by one from the lowest one $thresholds = array(1 => '1000', '1000000', '1000000000'); // Define thresholds // Set initial data $order = 1; $triplet = bcmod($num, '1000'); $lowest_nonzero_triplet_found = false; // indicates declension need for ordinal numerals while (bccomp($num, '0') == 1) { if (bccomp($triplet, '0') == 1) { $with_declension = false; // Whether to decline the last numerical (for ordinal numerals only) if (!$lowest_nonzero_triplet_found) { $with_declension = true; } // Define set of nouns $triplet_noun = NULL; $triplet_gender = 0; $triplet_subject_type = 0; switch ($order) { case 1: $triplet_noun = $noun; $triplet_gender = $gender; $triplet_subject_type = $subject_type; break; case 2: // Use internal noun for thousands $triplet_noun = $nouns['thousand']; $triplet_gender = 2; $triplet_subject_type = 1; break; case 3: // Use internal noun for millions $triplet_noun = $nouns['million']; $triplet_gender = 1; $triplet_subject_type = 1; break; case 4: // Use internal noun for billions $triplet_noun = $nouns['billion']; $triplet_gender = 1; $triplet_subject_type = 1; break; default: assert(false); // This must not happen! } if ($numeral_type == 1) { array_unshift($str, text::parse_cardinal_triplet($triplet, $order, $case, $triplet_gender, $triplet_subject_type, $triplet_noun, $with_declension, $noun)); // In this case, with_declension has nothing about declension but indicates the need to add custom noun // when order is more than 1 (actually, at the end of the result string) } elseif ($numeral_type == 2) { array_unshift($str, text::parse_ordinal_triplet($triplet, $order, $case, $triplet_gender, $triplet_subject_type, $triplet_noun, $with_declension, $gender, $subject_type, $noun)); } if (!$lowest_nonzero_triplet_found) { $lowest_nonzero_triplet_found = true; } } $num = bcdiv(bcsub($num, $triplet), '1000'); $triplet = bcmod($num, '1000'); $order++; } return implode(' ', $str); }