Demande d'avis, critiques, et commentaires

Ces trois fonctions (distinctes) proposent trois choses différentes :

> Number.prototype.formater : afficher un nombre avec des caractères numériques, mais en précisant le format souhaité (décimales, séparateurs)

> Number.prototype.enLettres : écrire en toutes lettres (en français) un nombre compris entre - 999 milliards et 999 milliards (avec toutes les règles et exceptions particulières de la langue française)

> Number.prototype.enRomains : obtenir l'équivalent d'un nombre en chiffres romains (pour les nombres supérieurs à 4999, plusieurs méthodes de représentation existent, mais ne font pas partie du paradigme originel, donc sont à implémenter en fonction des cas...

(voir signatures des fonctions pour le détail de l'utilisation, des paramètres, et des retours)
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// FONCTION : convertit un nombre en chaine de chiffres, avec le formatage souhaité
// PARAM #1 : "decimales" (number) : nombre de décimales souhaitées à l'affichage (ne modifie en rien le nombre courant) 
// PARAM #2 : "sepDecimal" (string) : SI ce param est présent, il remplace le "." comme séparateur décimal
// PARAM #3 : "sepMilliers" (string) : SI ce param est présent, il est utilisé comme séparateur des milliers/millions/milliards/etc.
// RETOUR : chaine représentant le nombre courant
Number.prototype.formater = function(decimales, sepDecimal, sepMilliers) {
   var resultat = this.toFixed(decimales);
   if (sepDecimal) resultat = resultat.replace(/\./, sepDecimal);
   if (sepMilliers) {
      var offset = 0;
      var posPoint = resultat.indexOf((sepDecimal)?sepDecimal:".");
      if (posPoint == -1)
         posPoint = resultat.length;
      while ((posPoint - offset) > 3) {
         resultat = resultat.inserer(sepMilliers, (posPoint - offset - 3));
         offset += 3;
      }
   }
   return resultat;
}
 
// FONCTION : convertit le nombre courant en toutes lettres (sans l'éventuelle partie décimale) 
// RETOUR : chaine représentant le nombre courant
Number.prototype.enLettres = function() {
   if (Math.abs(this) > 999999999999)
      return false;   
   var negatif;
   if (this < 0)
      negatif = true;   
   var chaine = Math.abs(this).toFixed();
   var resultat = "";
 
   // tableau de correspondance pour tout nombre compris entre 0 et 99
   // on accède par exemple à "42" par >>> nombresFr[4][2] 
   var nombresFr = [
      ["zéro", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"],
      ["dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"],
      ["vingt", "vingt et un", "vingt-deux", "vingt-trois", "vingt-quatre", "vingt-cinq", "vingt-six", "vingt-sept", "vingt-huit", "vingt-neuf"],
      ["trente", "trente et un", "trente-deux", "trente-trois", "trente-quatre", "trente-cinq", "trente-six", "trente-sept", "trente-huit", "trente-neuf"],
      ["quarante", "quarante et un", "quarante-deux", "quarante-trois", "quarante-quatre", "quarante-cinq", "quarante-six", "quarante-sept", "quarante-huit", "quarante-neuf"],
      ["cinquante", "cinquante et un", "cinquante-deux", "cinquante-trois", "cinquante-quatre", "cinquante-cinq", "cinquante-six", "cinquante-sept", "cinquante-huit", "cinquante-neuf"],
      ["soixante", "soixante et un", "soixante-deux", "soixante-trois", "soixante-quatre", "soixante-cinq", "soixante-six", "soixante-sept", "soixante-huit", "soixante-neuf"],
      ["soixante-dix", "soixante et onze", "soixante-douze", "soixante-treize", "soixante-quatorze", "soixante-quinze", "soixante-seize", "soixante-dix-sept", "soixante-dix-huit", "soixante-dix-neuf"],
      ["quatre-vingt", "quatre-vingt-un", "quatre-vingt-deux", "quatre-vingt-trois", "quatre-vingt-quatre", "quatre-vingt-cinq", "quatre-vingt-six", "quatre-vingt-sept", "quatre-vingt-huit", "quatre-vingt-neuf"],
      ["quatre-vingt-dix", "quatre-vingt-onze", "quatre-vingt-douze", "quatre-vingt-treize", "quatre-vingt-quatorze", "quatre-vingt-quinze", "quatre-vingt-seize", "quatre-vingt-dix-sept", "quatre-vingt-dix-huit", "quatre-vingt-dix-neuf"]
   ];
   var grandeursFr = [["cent", "mille", "million", "milliard"], ["cents", "mille", "millions", "milliards"]];
 
   // découpage de la chaine en blocs de 3 chiffres, en partant des unités
   // par exemple, pour le nombre courant 42150, on obtient à ce stade le tableau suivant : tabBloc >>> ["42", "150"] 
   var blocs = [];
   var longueur = chaine.length;
   while (longueur > 0) {
      if (longueur > 3) {
         blocs.splice(0, 0, chaine.substr((longueur - 3), 3));
         chaine = chaine.substr(0, longueur - 3);
      }
      else {
         blocs.splice(0, 0, chaine);
         chaine = "";
      }
      longueur = chaine.length;
   }
 
   // boucle sur les blocs : découpage du bloc courant, calcul de la chaine correspondante au bloc courant, stockage dans le tabResultat
   var tabResultat = [], tabBloc, bloc;
   for (var i = 0; i < blocs.length; ++i) {
      bloc = blocs[i];      
      tabBloc = [];
      for (var j = 0; j < bloc.length; ++j)
         tabBloc.push(parseInt(bloc.substr(j, 1), 10));
      while (tabBloc.length < 3)
         tabBloc.splice(0, 0, 0);      
      var sousResultat = nombresFr[tabBloc[1]][tabBloc[2]];
      if (tabBloc[0] > 1) {
         var exception100 = (tabBloc[0] > 1) && (sousResultat == "zéro") && (i == (blocs.length - 1));
         var centaines = nombresFr[0][tabBloc[0]] + " " + grandeursFr[(exception100) ? 1 : 0][0];
         tabResultat.push(centaines + ((sousResultat == "zéro") ? "" : " " + sousResultat));
      }
      else if (tabBloc[0] == 1)
         tabResultat.push("cent" + ((sousResultat == "zéro") ? "" : " " + sousResultat));
      else if (sousResultat != "zéro")
         tabResultat.push(sousResultat);         
      if ((blocs.length > (i + 1)) && (bloc != "000")) {
         var grandeur = grandeursFr[(tabResultat[i] == "un") ? 0 : 1][blocs.length - i - 1];
         tabResultat[((i == (blocs.length - 2)) && (bloc == "1")) ? (tabResultat.length - 1) : tabResultat.length] = grandeur;
      }      
      if ((bloc.match(/80$/)) && (blocs.length == (i + 1)))
         tabResultat[tabResultat.length - 1] = tabResultat[tabResultat.length - 1].replace(/quatre\-vingt/, "quatre-vingts");
   }
   resultat = tabResultat.join(" ");
   return (((negatif) ? "moins " : "") + resultat) || nombresFr[0][0];
}
 
// FONCTION : convertit le nombre courant (sa valeur entière arrondie) en chiffres romains ( valeur minimum : 1 ) 
// RETOUR : chaine représentant le nombre courant
Number.prototype.enRomains = function() {
   var tab = [ ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"],
               ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
               ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],// "?" >>> 5000 existe ? (à vérifier) 
               ["", "M", "MM", "MMM", "M?", "?", "?M", "?MM", "?MMM", "M!"],// "!" >>> 10000 existe ? (à vérifier) 
   ];
   if (this < 1 || this > 9999)
      return false;
   var chaine = this.toFixed(), resultat = "", j = 0;
   for (var i = chaine.length - 1; i >= 0; --i)
      resultat = tab[j++][parseInt(chaine.substr(i, 1), 10)] + resultat;      
   return resultat;
}