syntaxe de --> if $a différent de $b+$c+$d

syntaxe de --> if $a différent de $b+$c+$d - PHP - Programmation

Marsh Posté le 15-03-2008 à 23:58:01    

Bonjour,
 
je recherche la syntaxe correcte pour la fonction IF
 
les variables sont de type :  decimal(11,2)  -->  $a $b $c $d
 
logique:  si $a est différent de la somme de $b $c $d  
 
--------
 
mon code :  if ( $a!= $b+$c+$d)
 
resultat : quelques résultats en trop sont affichés ??!!  
Pourquoi ?
 
--------
Piste de Solution:
1- mon code est-il correct ? " if ( $a!= $b+$c+$d) "
2- le choix de type de variable est-il correct pour variable monétaire à 2 décimale ? "decimal(11,2)"
--------
 
Merci de votre aide.
 


---------------
Vive l'entraide!
Reply

Marsh Posté le 15-03-2008 à 23:58:01   

Reply

Marsh Posté le 16-03-2008 à 03:08:57    

le truc de malade :D

 

impossible d'afficher ok avec ce code :

Code :
  1. $a=11.4;
  2. $b=4.3;
  3. $c=7.1;
  4.  
  5. if($a==$b+$c){
  6.     echo 'ok';
  7. }else{
  8.     echo 'pas oki<br />';
  9.     var_dump($a);
  10.     var_dump($b+$c);
  11. }


et voici le resultat obtenu :

Code :
  1. pas oki
  2. float(11.4) float(11.4)
 


celle la on me l'avait jamais faite, j'aimerais bien voir ou est le probleme quand meme :s

 


EDIT : j'ai fini par l'avoir mon ok mais je ne suis toujours pas convaincu, c'est surtout le resultat des var_dump qui me trouble :s
voici comment j'obtient mon fameux OK

Code :
  1. $a=11.4;
  2. $b=4.3;
  3. $c=7.1;
  4.  
  5. $d=$b+$c;
  6.  
  7. if($a==settype($d, 'float')){
  8. //if($a==$d){ //marche pas !
  9.     echo 'ok';
  10. }else{
  11.     echo 'pas oki<br />';
  12.     var_dump($a);
  13.     var_dump($b+$c);
  14. }


là je peux aller me coucher :D

 

Dernier Edit : http://theserverpages.com/php/manu [...] .float.php


Message édité par naeh le 16-03-2008 à 03:49:44
Reply

Marsh Posté le 16-03-2008 à 09:05:37    


J'ai pas réussi avec ta solution :??:  
 
J'ai été sur ton lien : Dernier Edit : htp://theserverpages.com/php/manu [...] .float.php
et il est suggérer de ne pas faire d'opération ou de comparaison avec ce type de variable décimale.
 
 
 
Je crois que ce que j'ai besoin de savoir c'est :
quel type de variable dois-je utilisé pour faire de la comptabilité  
et quelles sont les fonctions pour pouvoir additionner soustraire et comparer ( =  <> etc.. )
 
Example de donnée à insérer dans la variable:     10.99      4.21      5.00      
 
Dans MySQL, j'ai choisi decimal (11,2) - c'est peut-être pas le bon choix !!
 
Je cherche dans les tutoriels mais je trouve pas ...

Reply

Marsh Posté le 16-03-2008 à 11:54:41    

La compta en php, que du bonheur :whistle:
 
Rien de bien compliqué, faut juste avoir à l'esprit que le typage n'est pas la prédilection de php. Faut caster sinon il considère que c'est une chaine :D

Code :
  1. $a = '9.1';
  2. $b = '4.1';
  3. $c = '5.00';
  4.  
  5. var_dump($a,$b,$c);
  6.  
  7. if( (float) $a !== (float) $b + $c  ){
  8.    echo 'pas égal';
  9. }
  10. else{
  11.     echo 'égal';
  12. }


 
Pour ta question c'est ici

Reply

Marsh Posté le 16-03-2008 à 13:23:09    

leflos5 a écrit :

La compta en php, que du bonheur :whistle:
 
Rien de bien compliqué, faut juste avoir à l'esprit que le typage n'est pas la prédilection de php. Faut caster sinon il considère que c'est une chaine :D

Code :
  1. $a = '9.1';
  2. $b = '4.1';
  3. $c = '5.00';
  4.  
  5. var_dump($a,$b,$c);
  6.  
  7. if( (float) $a !== (float) $b + $c  ){
  8.    echo 'pas égal';
  9. }
  10. else{
  11.     echo 'égal';
  12. }


 
Pour ta question c'est ici


 
 
 
ton code n'est pas toujours vrais, il répond différemment en fonction des valeurs données, avec mes valeurs (post plus haut de $a, $b, et $c) il te retournera "pas égal".
 
encore un mystère PHPFlottant ?  :pt1cable:

Reply

Marsh Posté le 16-03-2008 à 21:45:59    

Sisi, vérifie, justement je vérifiais que ça marchais bien avec les chaines, mais bien entendu, j'ai commencé avec des numériques ;)
 
En effet, il n'y a pas de logique à utiliser des chaines...

Reply

Marsh Posté le 17-03-2008 à 14:19:34    

leflos5 a écrit :

Sisi, vérifie, justement je vérifiais que ça marchais bien avec les chaines, mais bien entendu, j'ai commencé avec des numériques ;)

 

En effet, il n'y a pas de logique à utiliser des chaines...

 


Non non, ce code m'afficher "pas egal" :

Code :
  1. $a = '11.4';
  2.   $b = '4.3';
  3.   $c = '7.1';
  4.  
  5.   var_dump($a,$b,$c);
  6.  
  7.   if( (float) $a !== (float) $b + $c  ){
  8.      echo 'pas égal';
  9.   }
  10.   else{
  11.       echo 'égal';
  12.   }
  13.  
  14. //resultat : string(4) "11.4" string(3) "4.3" string(3) "7.1" pas égal
 


Message édité par naeh le 17-03-2008 à 14:20:27
Reply

Marsh Posté le 17-03-2008 à 16:40:34    

En effet :whistle:
Ce coupe semble assez étrange...
 
Aucune idée, une erreur de calcul proc, une erreur de représentation interne, ... :??:

Reply

Marsh Posté le 17-03-2008 à 16:46:09    

ha le coup de la comparaison des float (problème qui ne touche pas que php)
 
un peu de lecture : http://fr.php.net/float

Citation :

Ne faites donc jamais confiance aux nombres à virgule jusqu'à leur dernière décimale et ne comparez jamais ces nombres avec l'opérateur d'égalité.


 
plusieurs solutions pour contourner le problème :
- convertir en string et comparer :

Code :
  1. function float_equal($f1, $f2) {
  2.    if ( (string) $f1 == (string) $f2) return true
  3.    else return false;
  4. }


- bidouiller :

Code :
  1. function float_equal($f1, $f2)
  2. {
  3.    return ($f1 > $f2) ? (false) : (!($f1 < $f2));
  4. }


 
...etc

Reply

Marsh Posté le 17-03-2008 à 16:57:22    

Ptin le massacre [:prozac]  
 
ON NE FAIT JAMAIS DE CALCULS MONETAIRES AVEC DES FLOTTANTS
 
Et encore moins via des horreurs genre cast en string, c'est quoi ces conneries [:mlc]
 
wmjay, normalement on utilise effectivement un type décimal (flottant à précision arbitraire), mais PHP n'en a pas vraiment, il faut donc faire autrement:
 

  • Dans tous les cas, tu risques de devoir utiliser un type entier dans mysql plutôt qu'un décimal
  • Si tu l'as, utiliser l'extension PHP bcmath, c'est pas des plus simples à utiliser, mais ça devrait marcher
  • Sinon, voir du côté de GMP, mais c'est beaucoup plus compliqué que bcmath
  • Enfin, si tu veux te simplifier la vie (ou si ni bcmath ni gmp ne sont dispos) gère tout en entiers en comptant soit les centimes soit les centièmes de centimes (selon les arrondis que tu dois faire/peux te permettre, si c'est dans le cadre d'un truc genre ecommerce avec gestion de vraie monnaie, je conseille d'aller voir un spécialiste du domaine parce que se planter là dessus peut coûter très cher quand le fisc débarque et audite)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-03-2008 à 16:57:22   

Reply

Marsh Posté le 17-03-2008 à 17:51:00    

Merci !  
Pour toutes opérations sur des nombres flottants
- la vraie solution, c'est bcmath ou gmp.  
 
Mais ........  
 
Sans utiliser bcmath et GMP --->  
1- est-ce que je peux additionner des flottants sans erreur ?
2- et ensuite  comparer les sommes en string ????
 
Additionner une série de flottants  
et  
Comparer les résultats  
-----c'est tout ce que j'ai besoin !!  
 
 

Reply

Marsh Posté le 17-03-2008 à 17:54:50    

wmjay a écrit :

1- est-ce que je peux additionner des flottants sans erreur ?
2- et ensuite  comparer les sommes en string ????

 

Additionner une série de flottants
et
Comparer les résultats  
-----c'est tout ce que j'ai besoin !!


Relis mon post.

 

La 2e ligne pour être précis.

 

Et la 3e en bonus.


Message édité par masklinn le 17-03-2008 à 17:55:08

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 17-03-2008 à 18:04:36    

en tout cas c'est très interessant a savoir tout ça :)

Reply

Marsh Posté le 17-03-2008 à 18:48:37    

Au final, je pense que la meilleure solution si on est en précision fixe c'est de s'en passer et la rajoutée après en effet ;)
 
Mais si t'as besoin de petits calculs, si tu regardes c'est la comparaison qui pose soucis alors qu'en regardant la valeur y'a pas de problème l'addition se fait bien ;)

Reply

Marsh Posté le 17-03-2008 à 21:23:45    

Et pourtant ça fonctionne !!!
 
Si on revient à l'énoncé du 1er post

Code :
  1. les variables sont de type :  decimal(11,2)  -->  $a $b $c $d
  2. logique:  si $a est différent de la somme de $b $c $d


Voici ma solution :

Code :
  1. $total=$b+$c+$d;
  2. if ( (string) $a != (string) $total )  {echo"ok";}


 
Et je promet d'apprendre bcmath et GMP dans un avenir rapprocé :lol:  
 
Merci à tous !  :hello:

Reply

Marsh Posté le 18-03-2008 à 17:17:59    

Si je me plante pas, la raison provient de la manière dont sont représentés les nombres sur un ordinateur : tout est stocké en binaire, donc sous forme de sommes de puissances de 2.
 
Ex : 0.25 = 1/4 = 2^(-2)
La valeur 0.25 peut donc être stockée de façon précise dans une variable de type float, mais si on prend 0.1, qui n'est pas une puissance de 2, l'ordinateur va le stocker sous la forme d'une somme de puissances qui sera le plus proche possible de 0.1
 
Pendant mes premiers cours de programmation, on m'avait expliqué que les comparaisons d'égalité entre doubles et floats ne devaient jamais utiliser ==, mais un écart epsilon.
 
On définit par exemple epsilon = 0.0000000001 et ensuite on vérifie l'égalité de deux float ainsi :
 

Code :
  1. double epsilon = 0.0000000000001;
  2. float f1,f2;
  3. if (abs(f1 - f2) < epsilon) {
  4. echo "ok";
  5. } else {
  6. echo "c'est pas ok !";
  7. }


Reply

Marsh Posté le 18-03-2008 à 17:20:05    

astryad a écrit :

Si je me plante pas, la raison provient de la manière dont sont représentés les nombres sur un ordinateur : tout est stocké en binaire, donc sous forme de sommes de puissances de 2.
 
Ex : 0.25 = 1/4 = 2^(-2)
La valeur 0.25 peut donc être stockée de façon précise dans une variable de type float, mais si on prend 0.1, qui n'est pas une puissance de 2, l'ordinateur va le stocker sous la forme d'une somme de puissances qui sera le plus proche possible de 0.1
 
Pendant mes premiers cours de programmation, on m'avait expliqué que les comparaisons d'égalité entre doubles et floats ne devaient jamais utiliser ==, mais un écart epsilon.
 
On définit par exemple epsilon = 0.0000000001 et ensuite on vérifie l'égalité de deux float ainsi :
 

Code :
  1. double epsilon = 0.0000000000001;
  2. float f1,f2;
  3. if (abs(f1 - f2) < epsilon) {
  4. echo "ok";
  5. } else {
  6. echo "c'est pas ok !";
  7. }




Bordel mais c'est pas possible, vous êtes tous ravagés ou quoi?
 
Faut le répéter combien de fois? Il ne faut JAMAIS utiliser des flottants IEEE 754 quand on manipule des sommes monétaires


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 18-03-2008 à 17:24:15    

Je vois pas où j'ai dit le contraire ...
 
J'essayais juste de donner une explication, et accessoirement, en dehors des sommes monétaires, il peut très bien arriver d'avoir à comparer des float ou double.

Reply

Marsh Posté le 18-03-2008 à 23:46:06    

masklinn a écrit :


Bordel mais c'est pas possible, vous êtes tous ravagés ou quoi?
 
Faut le répéter combien de fois? Il ne faut JAMAIS utiliser des flottants IEEE 754 quand on manipule des sommes monétaires


Mais il n'y a pas que les monétaires qui peuvent être représentés par des flottants :o


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 19-03-2008 à 08:08:10    

kao98 a écrit :


Mais il n'y a pas que les monétaires qui peuvent être représentés par des flottants :o


Peut-être, mais ce topic est spécifiquement sur leur utilisation dans un cadre monétaire.
 
Et de toute façon, si les gens veulent connaître les limites des flottants IEEE 754, il y a une ressource claire, unique et à peu près finale sur le sujet: What Every Computer Scientist Should Know About Floating-Point Arithmetic


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-03-2008 à 21:07:10    

:bounce: [b]Attention - C'a fonctionne pourtant !!  Mais ...  pourquoi ?? ...- :bounce:  
--- Parce que je ne fais qu'additionner les décimales ...
              - qui proviennent de la base de données format décimale (x,2)
--- Si je veux multiplier ou calculer des pourcentages ...  ça ne marche pas !!
              - parce qu' il y a des chiffre après la 2ème décimale...
 
Donc: même si ça fonctionne, je suis d'accord avec Masklinn :

masklinn a écrit :

Bordel mais c'est pas possible, vous êtes tous ravagés ou quoi?
 
Faut le répéter combien de fois? Il ne faut JAMAIS utiliser des flottants IEEE 754 quand on manipule des sommes monétaires


 :bounce: - Voici la solution en bcmath ---> : :bounce:  

Code :
  1. $total=bcadd($b,$c,2);
  2. $total=bcadd($total,$d,2);
  3. if ( (string) $a != (string) $total )  {echo"ok";}

-ligne 1: addition de $b et $c
-ligne 2: addition de $d à ($b+$c)
-ligne 3: si $a est différent de $a+b+$c  {ok - exécuter le code}
 
Orthographe de bcadd:
   bcadd ( $variable1, $variable2, nb de décimale )
             
 
Voilà !
 
Des commentaires ??? sinon , problème résolu !
Merci infiniment à tous !!

Reply

Marsh Posté le 19-03-2008 à 21:13:01    

La 3e ligne est fausse, il faut passer par bccomp et tester si son résultat est égal à 0


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-03-2008 à 21:22:23    

Et comparer avec number_format() ?  :heink:  
 

Citation :


string number_format ( float $number [, int $decimals [, string $dec_point ]], string $thousands_sep )


---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 19-03-2008 à 21:38:45    

CyberDenix a écrit :

Et comparer avec number_format() ?  :heink:  
 

Citation :


string number_format ( float $number [, int $decimals [, string $dec_point ]], string $thousands_sep )



 [:prozac]  [:prozac]  [:prozac]  
 
number_format ça sert à formatter des nombres pour pouvoir les afficher de manière acceptable pour l'utilisateur (genre "1 000 000,00" au lieu de "1000000.00). Pas à faire des calculs, et sûrement pas à les comparer.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-03-2008 à 21:43:28    

Si tu veux te limiter à un certain nombre de décimales, ça marche plutôt pas mal (cf la comptabilité évoquée par wmjay)  ;)  
 
Maintenant c'est sûr que si tu veux faire du calcul de précision il faut autre chose...  :whistle:


Message édité par CyberDenix le 19-03-2008 à 21:44:32

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed