Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/03/2008, 18h53   #1
Membre à l'essai
 
Inscription : mai 2004
Messages : 195
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 195
Points : 20
Points : 20
Par défaut mystère d'une soustraction

Bonjour,

Je n'y comprends rien !!!
Il s'agit d'une simple soustraction afin de vérifier la balance d'une écriture comptable.
Client - TVA = Produit
Autrement il y a un problème d'arrondi à vérifier.

Code :
1
2
3
4
 
if ($cpt_cli - $cpt_tva != $cpt_prod)
echo "ATTENTION, l'écriture de $co_id ne balance pas.
Cli = $cpt_cli | Tva = $cpt_tva | Prod = $cpt_prod" . '<br>';
Le message d'alerte s'affiche toujours.
Or, les chiffres sont toujours exacts, les décimales étant bien marquées par un . et non pas par une virgule.

Par exemple, message réel :
ATTENTION, l'écriture de 2980 ne balance pas. Cli = 99.1 | Tva = 17.46 | Prod = 81.64

Où est le défaut ?

Merci d'avance.
boteha est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 19h26   #2
Membre Expert
 
Avatar de darkstar123456
 
Inscription : mars 2008
Messages : 1 180
Détails du profil
Informations personnelles :
Âge : 28
Localisation : Belgique

Informations forums :
Inscription : mars 2008
Messages : 1 180
Points : 1 357
Points : 1 357
Envoyer un message via Skype™ à darkstar123456
Essaye
Code :
1
2
3
4
 
if ( ($cpt_cli - $cpt_tva) != $cpt_prod)
echo "ATTENTION, l'&eacute;criture de $co_id ne balance pas.
Cli = $cpt_cli | Tva = $cpt_tva | Prod = $cpt_prod" . '<br>';
Il vaut mieux toujours entourer les opérations de parenthèse ;-) (même dans le cas de multiple opérations afin d'être certain du résultat)
darkstar123456 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 19h43   #3
Membre actif
 
Avatar de renaudjuif
 
Inscription : avril 2006
Messages : 300
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 300
Points : 174
Points : 174
c'est d'autant plus bizarre que
Code :
1
2
 
strcmp(($cpt_cli - $cpt_tva),$cpt_prod)
retourne bien 0 ...
Il n'y aurait pas un problème de typage derrière ça ?
__________________
C'est curieux chez les marins ce besoin de faire des phrases !
renaudjuif est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 19h45   #4
Débutant
 
Homme Samuel M. K. FOLI-AWLI
Inscription : avril 2003
Messages : 50
Détails du profil
Informations personnelles :
Nom : Homme Samuel M. K. FOLI-AWLI
Localisation : Togo

Informations forums :
Inscription : avril 2003
Messages : 50
Points : 43
Points : 43
Je ne pense pas que ce soit les parentheses parce que jai stocke le resultat dans une variable avant de tester la comparaison et cela n'avait pas marcher.
Essaye number_format() pour formater le resultat de la difference et le produit. Ca a marche chez moi en tout cas.

a+
fofovi72 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 19h48   #5
Membre Expert
 
Avatar de darkstar123456
 
Inscription : mars 2008
Messages : 1 180
Détails du profil
Informations personnelles :
Âge : 28
Localisation : Belgique

Informations forums :
Inscription : mars 2008
Messages : 1 180
Points : 1 357
Points : 1 357
Envoyer un message via Skype™ à darkstar123456
Citation:
Envoyé par renaudjuif Voir le message
c'est d'autant plus bizarre que
Code :
1
2
 
strcmp(($cpt_cli - $cpt_tva),$cpt_prod)
retourne bien 0 ...
Il n'y aurait pas un problème de typage derrière ça ?
sans les parenthèses t'as essayé si ça retournait bien 0 ? En général, en PHP si tu met pas les parenthèse il interprète ça comme un echo, c'est à cause de la concaténation.

Exemple :
Code :
1
2
3
4
5
6
7
8
9
 
$a = 5;
$b = 2;
 
echo "$a <br />"; // affiche : 5
 
echo "$a - $b"; // affiche : 5 - 2
 
echo ($a - $b) // affiche : 3
darkstar123456 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 19h56   #6
Membre actif
 
Avatar de renaudjuif
 
Inscription : avril 2006
Messages : 300
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 300
Points : 174
Points : 174
number_format marche bien, c'est vrai.
mais ça retourne une string, c'est quand même bizarre de faire un calcul en comparant des chaines de caractères.
__________________
C'est curieux chez les marins ce besoin de faire des phrases !
renaudjuif est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 20h25   #7
Membre à l'essai
 
Inscription : mai 2004
Messages : 195
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 195
Points : 20
Points : 20
Bonsoir,

Merci beaucoup de vos réponses.

La piste du typage est plausible, mais j'ai testé les trois valeurs avec is_float, c'est bien du float.

Je me demande si ce n'est pas une des valeurs qui a plus de décimales que les autres, d'où erreur systématique.
Je vous dit ça après le dîner...

Merci encore.
boteha est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 20h29   #8
Débutant
 
Homme Samuel M. K. FOLI-AWLI
Inscription : avril 2003
Messages : 50
Détails du profil
Informations personnelles :
Nom : Homme Samuel M. K. FOLI-AWLI
Localisation : Togo

Informations forums :
Inscription : avril 2003
Messages : 50
Points : 43
Points : 43
Si tu n'as pas trouver mieux essaye

Code :
 $valeur = (float) number_format($valeur,n);
Cela te permet d'uniformiser les valeurs et d'avoir a la fin des float toujours
fofovi72 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 21h28   #9
Membre à l'essai
 
Inscription : mai 2004
Messages : 195
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 195
Points : 20
Points : 20
Re-bonsoir

J'ai fait le test suivant :

Code :
1
2
3
4
5
6
 
echo $cpt_cli . '<br>';
echo $cpt_tva . '<br>';
echo $cpt_prod . '<br>';
echo $cpt_cli - $cpt_tva - $cpt_prod . '<br>';
echo round ($cpt_cli - $cpt_tva - $cpt_prod, 2) . '<br>';
et cela donne ce résultat très bizarre :
99.1
17.46
81.64
1.42108547152E-14
0

Donc, de la soustraction de 3 nombres à 2 décimales, PHP trouve un micro-chouia qui n'existe pas.
Je ne dis pas que c'est un bug de PHP, peut-être de mon serveur...
En limitant le résultat à 2 décimales (ou même à 10, j'ai essayé) par round, cela devient bon.

Donc, mon test devient :
Code :
1
2
 
if (round ($cpt_cli - $cpt_tva - $cpt_prod, 2) != 0) echo 'Problème !!!';
Donc, en pratique, le problème semble résolu.

Mais d'où sort ce 1.42108547152E-14 ???

Vous avez idée ?

Merci d'avance.

PS : dans les calculs, il faut utiliser round (), pas number_format () qui est une fonction de présentation, pas de calcul.
boteha est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 21h41   #10
Membre Expert
 
Avatar de darkstar123456
 
Inscription : mars 2008
Messages : 1 180
Détails du profil
Informations personnelles :
Âge : 28
Localisation : Belgique

Informations forums :
Inscription : mars 2008
Messages : 1 180
Points : 1 357
Points : 1 357
Envoyer un message via Skype™ à darkstar123456
Je crois que le 1.42108547152E-14 provient du fait qu'une soustraction n'est pas commutative et donc il ne sait pas trop par où commencer, du coup il retourne la valeur minimale d'un nombre en PHP
darkstar123456 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 21h48   #11
Membre à l'essai
 
Inscription : mai 2004
Messages : 195
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 195
Points : 20
Points : 20
Bonsoir,

Merci de ta réponse, c'est bon à savoir...
boteha est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 21h49   #12
Membre actif
 
Avatar de renaudjuif
 
Inscription : avril 2006
Messages : 300
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 300
Points : 174
Points : 174
Je crois que j'ai trouvé... j'avais eu le même problème en javascript...
C'est un pb de nombre à virgule flotante.

si vous faites
Code :
1
2
3
 
echo number_format($cpt_cli - $cpt_tva,50,"."," ")."<br>";
echo number_format($cpt_prod,50,"."," ")."<br>";
ça donne ça :
81.63999999999998635757947340607643127441406250000000
81.64000000000000056843418860808014869689941406250000

Donc c'est pas pareil
__________________
C'est curieux chez les marins ce besoin de faire des phrases !
renaudjuif est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2008, 21h53   #13
Membre à l'essai
 
Inscription : mai 2004
Messages : 195
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 195
Points : 20
Points : 20
Encore merci, je crois que je peux cocher résolu.
boteha est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h21.


 
 
 
 
Partenaires

Hébergement Web