PHP les grands nombres et la notation scientifique

18/02/2009

PHP gère les grands nombres sans trop de souci, malheureusement il arrive parfois que les bases de données retournent un grand nombre sous forme scientifique. Là où cela se complique c’est quand le nombre que nous voulons reformater est à virgule flottante. Laissez moi vous montrer.

Imaginons un nombre retourné par une base sous forme scientifique, par exemple //1.1e+6// qui correspond en fait à //1 100 000//. Ici la manière la plus simple pour représenter le nombre sous une jolie forme est: echo number_format(1.1e+6); 1 100 000

Pas trop d’effort, PHP a remis les choses en place. Voyons maintenant ce que donne //1.1234567e+6// qui est en fait la forme scientifique de //1 123 456.7//. **Notez bien la virgule !** et faisons de même: echo number_format(1.1234567e+6); 1,1231,457

Problème, on a perdu notre virgule et on a un arrondi… qu’à cela ne tienne, nous allons reformater le nombre en flottant: echo number_format(1.1234567e+6,2); 1,123,456.70

Jusque là, on a trouvé une solution… Pour la plupart des cas cela va vous permettre de corriger le problème, seulement j’ai eut un cas où je devais reformater des prix élevés formatés en notation scientifique mais il fallait que je ne fasse apparaitre la virgule que dans le cas où il y a une partie décimale…

Voilà donc ma méthode, certainement pas optimale, mais qui fonctionne: -je récupère la notation -je vérifie que la valeur entière est différente de la valeur sous forme décimale -si oui, je met “2” en paramètre à number_format pour demander deux chiffres après la virgule -si non je met “null” en paramètre à number_format pour supprimer la virgule Voici: function format_number($num, $floatsep=",", $thouthandsep=" "){ $float = null; if((int)$num != (float)$num ) $float = 2; return number_format($num,$float,$floatsep,$thouthandsep); }

Remarquez “\$floatsep” et “\$thouthandsep” qui sont respectivement les séparateur de virgule et de milier (différent pour les américains et les français) qui peuvent être utiles (voir plus bas). Testons notre fonction:

php > echo format_number(1.1234567e+6);
1 123 456,70
php > echo format_number(1.123456e+6);
1 123 456

Et voilà… **ATTENTION** n’envoyez **pas de chaine de caractère** mais bien des nombres **sans guillemets** à la fonction. J’entend par là que la notation scientifique n’est pas une chaine de caractères! Ne vous inquiétez pas vos base de données vous renvoient bien des variables de type __float__ ou __int__… Si vous englobez la notation scientifique dans une chaine de caractères, vous aurez à coup sûr un flottant car le test //(int)\$num != (float)\$num// sera **TOUJOURS VRAI** (les deux valeurs seront différentes… vous pouvez tester).

Bref, cette fonction me sert à formater des prix, mais vous pouvez vous en servir pour la suite. Par contre n’utilisez cette fonction qu’avant affichage car la valeur retournée est une chaine. La méthode pour pallier à cela:

#ici vous voyez le problème:
php > $a = format_number(1.1234567e+6);
php > $b = format_number(2.1234567e+6);
php > echo $a + $b;
3

#ici, on a beau faire ce qu'on veut... ça marche pas
php > $a = (float)format_number(1.1234567e+6);
php > $b = (float)format_number(2.1234567e+6);
php > echo $a + $b;
3

#la solution, mettre un séparateur de virgule "."
#et pas d'espace pour le spérateur de miliers:
php > $a = format_number(1.1234567e+6, '.', '');
php > $b = format_number(2.1234567e+6, '.', '');
php > echo $a + $b;
3246913.4
#pour le fun
php > format_number($a+$b)
3 246 913,40

En espérant que cela puisse vous servir.

Ça peut vous intéresser aussi


PHP 5.3 et les fonctions anonymes

Je les utilise depuis des lustres en Javascript et Java,...


Poste de développement PHP sous Fedora

Linux est un système parfait pour développer. Simple d’installation,...


Abstraction et interfaces PHP

Une question s’est levée lors de mon développement sur ...


Créer une extension PHP en C

Vous avez des contraintes de performances ? ou alors vous ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.