array( # 0-19 '', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', # 20-29 'vingt', 'vingt et un', 'vingt-deux', 'vingt-trois', 'vingt-quatre', 'vingt-cinq', 'vingt-six', 'vingt-sept', 'vingt-huit', 'vingt-neuf', # 30-39 'trente', 'trente et un', 'trente-deux', 'trente-trois', 'trente-quatre', 'trente-cinq', 'trente-six', 'trente-sept', 'trente-huit', 'trente-neuf', # 40-49 'quarante', 'quarante et un', 'quarante-deux', 'quarante-trois', 'quarante-quatre', 'quarante-cinq', 'quarante-six', 'quarante-sept', 'quarante-huit', 'quarante-neuf', # 50-59 'cinquante', 'cinquante et un', 'cinquante-deux', 'cinquante-trois', 'cinquante-quatre', 'cinquante-cinq', 'cinquante-six', 'cinquante-sept', 'cinquante-huit', 'cinquante-neuf', # 60-69 'soixante', 'soixante et un', 'soixante-deux', 'soixante-trois', 'soixante-quatre', 'soixante-cinq', 'soixante-six', 'soixante-sept', 'soixante-huit', 'soixante-neuf', # 70-79 'septante', 'septante et un', 'septante-deux', 'septante-trois', 'septante-quatre', 'septante-cinq', 'septante-six', 'septante-sept', 'septante-huit', 'septante-neuf', # 80-89 'huitante', 'huitante et un', 'huitante-deux', 'huitante-trois', 'huitante-quatre', 'huitante-cinq', 'huitante-six', 'huitante-sept', 'huitante-huit', 'huitante-neuf', # 90-99 'nonante', 'nonante et un', 'nonante-deux', 'nonante-trois', 'nonante-quatre', 'nonante-cinq', 'nonante-six', 'nonante-sept', 'nonante-huit', 'nonante-neuf' ), 'illi' => array('', 'm', 'b', 'tr', 'quatr', 'quint', 'sext'), 'maxilli' => 0, # voir plus loin 'de_maxillions' => '', # voir plus loin 'septante' => false, # valeurs possibles : (false|true) 'huitante' => false, # valeurs possibles : (false|true|'octante') 'nonante' => false, # valeurs possibles : (false|true) 'zilliard' => 1, # valeurs possibles : (0|1|2) 'rectif' => false, # valeurs possibles : (false|true) 'ordinal' => false, # valeurs possibles : (false|true|'nieme') 'separateur' => ' ' ); # Si le tableau $NEL['illi'] s'arrête à 'sext', alors les deux valeurs # suivantes sont respectivement '6' et ' de sextillions'. $NEL['maxilli'] = count($NEL['illi']) - 1; $NEL['de_maxillions'] = " de {$NEL['illi'][$NEL['maxilli']]}illions"; function enlettres_options($options, $separateur=NULL) { global $NEL; if ($options !== NULL) { $NEL['septante'] = ($options & NEL_SEPTANTE) ? true : false; $NEL['huitante'] = ($options & NEL_OCTANTE) ? 'octante' : (($options & NEL_HUITANTE) ? true : false); $NEL['nonante'] = ($options & NEL_NONANTE) ? true : false; $NEL['zilliard'] = ($options & NEL_AVEC_ZILLIARD) ? 2 : (($options & NEL_SANS_MILLIARD) ? 0 : 1); $NEL['rectif'] = ($options & NEL_RECTIF_1990) ? true : false; $NEL['ordinal'] = ($options & NEL_NIEME) ? 'nieme' : (($options & NEL_ORDINAL) ? true : false); } if ($separateur !== NULL) { $NEL['separateur'] = $separateur; } } function enlettres_par3($par3) { global $NEL; if ($par3 == 0) return ''; $centaine = floor($par3 / 100); $par2 = $par3 % 100; $dizaine = floor($par2 / 10); # On traite à part les particularités du français de référence # 'soixante-dix', 'quatre-vingts' et 'quatre-vingt-dix'. $nom_par2 = NULL; switch ($dizaine) { case 7: if ($NEL['septante'] === false) { if ($par2 == 71) $nom_par2 = 'soixante et onze'; else $nom_par2 = 'soixante-' . $NEL['1-99'][$par2 - 60]; } break; case 8: if ($NEL['huitante'] === false) { if ($par2 == 80) $nom_par2 = 'quatre-vingts'; else $nom_par2 = 'quatre-vingt-' . $NEL['1-99'][$par2 - 80]; } break; case 9: if ($NEL['nonante'] === false) { $nom_par2 = 'quatre-vingt-' . $NEL['1-99'][$par2 - 80]; } break; } if ($nom_par2 === NULL) { $nom_par2 = $NEL['1-99'][$par2]; if (($dizaine == 8) and ($NEL['huitante'] === 'octante')) { $nom_par2 = str_replace('huitante', 'octante', $nom_par2); } } # Après les dizaines et les unités, il reste à voir les centaines switch ($centaine) { case 0: return $nom_par2; case 1: return rtrim("cent {$nom_par2}"); } # Assertion : $centaine = 2 .. 9 $nom_centaine = $NEL['1-99'][$centaine]; if ($par2 == 0) return "{$nom_centaine} cents"; return "{$nom_centaine} cent {$nom_par2}"; } function enlettres_illions($idx) { global $NEL; if ($idx == 0) { return ''; } $suffixe = ''; while ($idx > $NEL['maxilli']) { $idx -= $NEL['maxilli']; $suffixe .= $NEL['de_maxillions']; } return "{$NEL['illi'][$idx]}illions{$suffixe}"; } function enlettres_avec_illiards($idx) { global $NEL; if ($idx == 0) return false; switch ($NEL['zilliard']) { case 0: return false; case 2: return true; } return ($idx == 1); } function enlettres($nombre, $options=NULL, $separateur=NULL) { global $NEL; if ($options !== NULL or $separateur !== NULL) { $NELsave = $NEL; enlettres_options($options, $separateur); $nom = enlettres($nombre); $NEL = $NELsave; return $nom; } # On ne garde que les chiffres, puis on supprime les 0 du début $nombre = preg_replace('/[^0-9]/', '', $nombre); $nombre = ltrim($nombre, '0'); if ($nombre == '') { if ($NEL['ordinal'] === 'nieme') return 'zéroième'; else return 'zéro'; } $table_noms = array(); for ($idx = 0; $nombre != ''; $idx++) { $par6 = (int) substr($nombre, -6); $nombre = substr($nombre, 0, -6); if ($par6 == 0) continue; $nom_par3_sup = enlettres_par3(floor($par6 / 1000)); $nom_par3_inf = enlettres_par3($par6 % 1000); $illions = enlettres_illions($idx); if (enlettres_avec_illiards($idx)) { if ($nom_par3_inf != '') { $table_noms[$illions] = $nom_par3_inf; } if ($nom_par3_sup != '') { $illiards = preg_replace('/on/', 'ard', $illions, 1); $table_noms[$illiards] = $nom_par3_sup; } } else { switch($nom_par3_sup) { case '': $nom_par6 = $nom_par3_inf; break; case 'un': $nom_par6 = rtrim("mille {$nom_par3_inf}"); break; default: $nom_par3_sup = preg_replace('/(vingt|cent)s/', '\1', $nom_par3_sup); $nom_par6 = rtrim("{$nom_par3_sup} mille {$nom_par3_inf}"); break; } $table_noms[$illions] = $nom_par6; } } $nom_enlettres = ''; foreach ($table_noms as $nom => $nombre) { ## # $nombre est compris entre 'un' et # 'neuf cent nonante-neuf mille neuf cent nonante-neuf' # (ou variante avec 'quatre-vingt-dix-neuf') ## # $nom peut valoir '', 'millions', 'milliards', 'billions', ... # 'sextillions', 'sextilliards', 'millions de sextillions', # 'millions de sextilliards', etc. ## # Rectifications orthographiques de 1990 if ($NEL['rectif']) { $nombre = str_replace(' ', '-', $nombre); } # Nom (éventuel) et accord (éventuel) des substantifs $nom = rtrim("{$nombre} {$nom}"); if ($nombre == 'un') { # Un seul million, milliard, etc., donc au singulier # noter la limite de 1 remplacement, pour ne supprimer que le premier 's' # dans 'billions de sextillions de sextillions' $nom = preg_replace('/(illion|illiard)s/', '\1', $nom, 1); } # Ajout d'un séparateur entre chaque partie if ($nom_enlettres == '') { $nom_enlettres = $nom; } else { $nom_enlettres = $nom . $NEL['separateur'] . $nom_enlettres; } } if ($NEL['ordinal'] === false) { # Nombre cardinal : le traitement est fini return $nom_enlettres; } # Aucun pluriel dans les ordinaux $nom_enlettres = preg_replace('/(cent|vingt|illion|illiard)s/', '\1', $nom_enlettres); if ($NEL['ordinal'] !== 'nieme') { # Nombre ordinal simple (sans '-ième') return $nom_enlettres; } if ($nom_enlettres === 'un') { # Le féminin n'est pas traité ici. On fait la supposition # qu'il est plus facile de traiter ce cas à part plutôt # que de rajouter une option rien que pour ça. return 'premier'; } switch (substr($nom_enlettres, -1)) { case 'e': # quatre, onze à seize, trente à nonante, mille # exemple : quatre -> quatrième return substr($nom_enlettres, 0, -1) . 'ième'; case 'f': # neuf -> neuvième return substr($nom_enlettres, 0, -1) . 'vième'; case 'q': # cinq -> cinquième return $nom_enlettres . 'uième'; } # Tous les autres cas. # Exemples: deuxième, troisième, vingtième, trente et unième, # neuf centième, un millionième, quatre-vingt milliardième. return $nom_enlettres . 'ième'; } ?>