Précédent   Forum des professionnels en informatique > PHP > Langage > Fichiers
Fichiers Forum d'entraide sur les fichiers avec PHP. Avant de poster -> FAQ fichiers et Sources fichiers
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 28/04/2007, 07h14   #1
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
Par défaut bug hallucinant en php

Bonjour,

J'ai un bug très bizarre. Quand je fais un echo (100-99.99), çà devrait me retourner 0.01 et çà me retourne une valeur du type 0.010000526.
Hallucinant non !!!
Au début j'ai cru que çà venait de la bdd mais non juste avec un echo de 100-99.99 çà renvoie n'importe quoi.

Merci de votre aide
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2007, 19h38   #2
Membre émérite
 
Avatar de sharrascript
 
Homme Franck
Développeur Web indépendant
Inscription : avril 2007
Messages : 678
Détails du profil
Informations personnelles :
Nom : Homme Franck
Âge : 31
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur Web indépendant

Informations forums :
Inscription : avril 2007
Messages : 678
Points : 900
Points : 900
bonsoir,

Je n'ai pas essayé, mais moi j'aurais fait le calcul dans une variable et je retournerai cette même variable.

Code :
1
2
$a = 100 - 99,99;
echo $a;
Je ne sais pas si c'est une solution au pb, mais j'aurai essayé de t'aider :p

++
sharrascript est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2007, 00h16   #3
Invité de passage
 
Inscription : juin 2006
Messages : 11
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 11
Points : 2
Points : 2
Par défaut Euh...

Salut à toi
Voici un test que j'ai effectué en local :

Mon code :
Code :
1
2
3
4
5
6
7
8
<?php
 
echo 100-99.99;
 
$a = 100 - 99.99;
echo "<br />a = ".$a;
 
?>
Le résultat :
Citation:
Envoyé par Firefox
0.01
a = 0.01
Je vois pas trop où tu as peché ton 526 qui se trouve à la fin de ton truc, mais moi j'aurais tendance à dire que ça à à voir avec l'init de tes vars (leur type, vu que php le gère sans que tu le vois, ca se pourrait que y'ait eu merdouille) ou alors que si les données viennent d'une base, ben ca soit le traitement de ces données qui foire lors de leur récupération.

Sinon à part ça chez moi ca marche très bien (PHP5.1.4 / Apache 2.2.2)
Manwë06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2007, 04h34   #4
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
Bizarre effectivement, je viens de faire un test en mettant une variable à la place genre $a=100-99.99 çà retourne pareil une valeur éronnée
Donc çà vient d'autre chose, par contre mon test je le fais en ligne sur mon site et çà merde grave
j'ai créé un fichier calcul.php
<?php
echo 100-99.99;
?>
voilà et çà retourne n'importe quoi.
J'ai vu que mon hébergeur a une vieille version de php la 4.4.4, je prie pour que çà vienne pas de chez eux ou je suis mal.
Par contre, vous me confirmez que çà ne peut pas venir de ma version de php qui est installé chez moi qui doit etre assez ancienne je pense.

merci
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2007, 08h45   #5
Membre émérite
 
Avatar de sharrascript
 
Homme Franck
Développeur Web indépendant
Inscription : avril 2007
Messages : 678
Détails du profil
Informations personnelles :
Nom : Homme Franck
Âge : 31
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur Web indépendant

Informations forums :
Inscription : avril 2007
Messages : 678
Points : 900
Points : 900
Honnêtement je trouve ça très bizar,

Chez moi tout fonctionne et les valeurs sont corrects.

Dans tous les cas ça ne peu pas venir de ta version chez toi vu que tu fais les tests en ligne. Ta version ne peu influer sur celle de ton hébergeur.

Est-ce qu'un autre calcul fonctionne??

normalement même une version php3 devrais fonctionner.

Essai avec:

++
sharrascript est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2007, 09h50   #6
Membre chevronné
 
Avatar de Korko Fain
 
Étudiant
Inscription : août 2005
Messages : 632
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : août 2005
Messages : 632
Points : 632
Points : 632
Sans vouloir rentrer dans les détails du stockage et des calculs machines, je dirais que c'est tout à fait normal et que ce n'est pas un probleme de php mais un probleme du au codage en binaire des nombres. Et oui, l'ordinateur ne calcul pas en base10 (de 0 à 9) mais en base 2 (0 ou 1). Si nous avons des bonnes valeurs, ce n'est que du à un arrondi.

Petit algo sensé s'arreter mais avec la logique binaire de la machine, c'est une boucle infinie (et pourtant si vous regardez, il affiche $n = 1 MAIS $n != 1 étrange hein :p) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
 
$n = 0;
 
while($n != 1)
{
    echo($n.'<br />');
    $n += 0.1;
}
 
// On n'y arrivera jamais
echo('Fini');
 
?>
Korko Fain est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2007, 12h43   #7
Membre confirmé
 
Avatar de LhIaScZkTer
 
Inscription : mai 2004
Messages : 536
Détails du profil
Informations personnelles :
Âge : 30

Informations forums :
Inscription : mai 2004
Messages : 536
Points : 217
Points : 217


Moi je sais pas si c'est étrange mais je trouve ça normal puisque 1 n'est pas égal à 1.00.
N'est-ce pas dû au typage faible de php ? Je pense qu'il faudrait essaier de tester le type de la variable.

Dans ton algo Korko Fain tu initialises ta variable à 0 essaie un 0.00 et dans ton while essaie aussi un 1.00 pour voir

En java en tout cas on pourrait pas incrémenter un int de 0.1 ce qui est logique
LhIaScZkTer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2007, 13h39   #8
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
Bonjour à tous,

çà commence à me prendre le chou cette histoire je viens de passer en php5 et c'est toujours pareil et meme si on fait 100.00-99.99 c'est pareil j'en ai marre là franchement c'est quoi ce langage à 2 franc franchement. Je connais pas un langage qui soit incapable de faire un calcul de base tel que 100-99.99.
Je fais quoi de mon site moi du coup ???
Si mes calculs sont tous faux je peux rien faire.
J'aurais du faire en asp c'est pas possible çà me gave franchement là merci php franchement.
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2007, 14h00   #9
Membre expérimenté
 
Développeur Web
Inscription : avril 2006
Messages : 430
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2006
Messages : 430
Points : 538
Points : 538
T'as essayé de faire le calcul dans un autre langage (serveur) ?

Sinon, comme t'auras pu le constater, les autres ici ont les bons résultats, et ca m'étonnerait franchement qu'un bug comme celui-ci soit passé inapercu, de plus sur des version 4 et 5
__________________
Merci à Microsoft pour avoir transformé un métier relativement terne et basé sur une approche bêtement technique et rigoureuse des faits, en challenge quotidien, nécessitant une remise en question permanente à l'échelle du quart d'heure
bkill est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2007, 14h19   #10
Membre chevronné
 
Avatar de Korko Fain
 
Étudiant
Inscription : août 2005
Messages : 632
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : août 2005
Messages : 632
Points : 632
Points : 632
Essaye de faire des arrondi avec round. Si tu as des chiffres complets c'est justement pcq ton serveur est trop précis.

Et en php 1 == 1.00 mais 1 !== 1.00 (!== est l'inverse de ===)
Korko Fain est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 00h32   #11
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
je viens de faire un test chez free et c'est pareil même problème.
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 02h13   #12
Membre du Club
 
Inscription : octobre 2002
Messages : 67
Détails du profil
Informations personnelles :
Âge : 38
Localisation : Canada

Informations forums :
Inscription : octobre 2002
Messages : 67
Points : 69
Points : 69
Envoyer un message via MSN à Luc Raymond Envoyer un message via Skype™ à Luc Raymond
Citation:
Envoyé par pas30
Bonjour,

J'ai un bug très bizarre. Quand je fais un echo (100-99.99), çà devrait me retourner 0.01 et çà me retourne une valeur du type 0.010000526.
Hallucinant non !!!
Au début j'ai cru que çà venait de la bdd mais non juste avec un echo de 100-99.99 çà renvoie n'importe quoi.

Merci de votre aide
ce n'est pas un bug, on peut avoir qqchose de similaire en language C/C++
voir la doc en ligne de php: http://ca.php.net/manual/fr/language.types.float.php

Citation:
Précision des nombres décimaux
Il est fréquent que de simples fractions décimales telles que 0.1 ou 0.7 ne puissent être converties au format interne binaire sans une légère perte de précision. Cela peut conduire à des résultats étonnants : par exemple, floor((0.1+0.7)*10) retournera 7 au lieu de 8 car le résultat de la représentation interne est 7.9999999999....

Tout ceci est lié au fait qu'il est impossible d'exprimer certaines fractions en un nombre fini de chiffres. Par exemple 1/3 s'écrira 0.3333333... en mode décimal.
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é. Si vous avez besoin d'une précision particulière, reportez-vous au traitement des nombres de grande taille avec les bibliothèques BC ou GMP.

Code :
1
2
3
4
5
<?php
printf("%.15f", (19.6*100));
?>
 
sortie: 1960.000000000000227 (et non 1960, comme prévut )
Luc Raymond est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 13h50   #13
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
bonjour,

bizarre en effet tout çà. Mon problèm reste entier car quand je fais "update table set valeur=valeur-99.99 çà merde pareil
alors il faudrait arrondir le chiffre dans la base impossible non ???
C'est bizarre tout çà car aucun calcul du coup n'est correct ou exact avec php.
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 13h53   #14
Membre du Club
 
Inscription : octobre 2002
Messages : 67
Détails du profil
Informations personnelles :
Âge : 38
Localisation : Canada

Informations forums :
Inscription : octobre 2002
Messages : 67
Points : 69
Points : 69
Envoyer un message via MSN à Luc Raymond Envoyer un message via Skype™ à Luc Raymond
Citation:
Envoyé par pas30
bonjour,

bizarre en effet tout çà. Mon problèm reste entier car quand je fais "update table set valeur=valeur-99.99 çà merde pareil
alors il faudrait arrondir le chiffre dans la base impossible non ???
C'est bizarre tout çà car aucun calcul du coup n'est correct ou exact avec php.
bizarre quand même, car si tu fais un UPDATE, comme tu l'indiques, ce n'est pas php qui gère le calcul mais bien Mysql

ton champ 'valeur' est définit de quelle façon dans mysql?
Luc Raymond est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 14h25   #15
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
C'est trop fort ce truc lol
Vous ouvrez phpmyadmin et vous faites une requete
update table set nombre=nombre-99.99
avant il faut mettre dans nombre 100
çà retourne 0.01000051
Sinon mon nombre est définit en type double.
Donc mysql a le meme bug
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 14h33   #16
Membre du Club
 
Inscription : octobre 2002
Messages : 67
Détails du profil
Informations personnelles :
Âge : 38
Localisation : Canada

Informations forums :
Inscription : octobre 2002
Messages : 67
Points : 69
Points : 69
Envoyer un message via MSN à Luc Raymond Envoyer un message via Skype™ à Luc Raymond
Citation:
Envoyé par pas30
C'est trop fort ce truc lol
Vous ouvrez phpmyadmin et vous faites une requete
update table set nombre=nombre-99.99
avant il faut mettre dans nombre 100
çà retourne 0.01000051
Sinon mon nombre est définit en type double.
Donc mysql a le meme bug
arrête ce n'est pas un bug!!

tout comme indiqué dans la docu de mysql, les seuls types de champ permettant de stocker la valeur exacte (avec une décimale), sont les types DECIMAL et NUMERIC

Citation:
The DECIMAL and NUMERIC data types are used to store exact numeric data values. In MySQL, NUMERIC is implemented as DECIMAL. These types are used to store values for which it is important to preserve exact precision, for example with monetary data.
les champs float et double, sont des approximations des valeurs... je te conseil de changer ton type de données et refaire le test.. ensuite tu m'envois un chèque!!
Luc Raymond est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 20h20   #17
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
J'ai passé une colonne en DECIMAL et là catastrophe çà m'a viré les valeurs avec des décimales du coup j'ai perdu deux jours de ma base.
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 21h00   #18
Membre du Club
 
Inscription : octobre 2002
Messages : 67
Détails du profil
Informations personnelles :
Âge : 38
Localisation : Canada

Informations forums :
Inscription : octobre 2002
Messages : 67
Points : 69
Points : 69
Envoyer un message via MSN à Luc Raymond Envoyer un message via Skype™ à Luc Raymond
Citation:
Envoyé par pas30
J'ai passé une colonne en DECIMAL et là catastrophe çà m'a viré les valeurs avec des décimales du coup j'ai perdu deux jours de ma base.
le résultat était difficilement prévisible étant donné que tout dépend des valeurs que tu indiques. Je fais personnellement un backup de la table avant de faire un changement.

Luc Raymond est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 21h32   #19
Nouveau Membre du Club
 
Inscription : décembre 2006
Messages : 321
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 321
Points : 38
Points : 38
Par contre avec le format DECIMAL, il faut définir une taille et indiquer le nombre de chiffre après la virgule, c'est bien çà ???
çà me gene car un chiffre peut avoir aussi bien 2 chiffres après la virgule que 5 çà dépend.
Sinon pour la sauvegarde tu as raison mais je ne pensais vraiment pas que çà allait me faire ce truc je me suis pas méfié surtout qu'avec le nom du type 'DECIMAL' j'imaginais vraiment pas que çà allait m'enlever les chiffres après la virgule
pas30 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2007, 22h16   #20
Membre du Club
 
Inscription : octobre 2002
Messages : 67
Détails du profil
Informations personnelles :
Âge : 38
Localisation : Canada

Informations forums :
Inscription : octobre 2002
Messages : 67
Points : 69
Points : 69
Envoyer un message via MSN à Luc Raymond Envoyer un message via Skype™ à Luc Raymond
Citation:
Envoyé par pas30
Par contre avec le format DECIMAL, il faut définir une taille et indiquer le nombre de chiffre après la virgule, c'est bien çà ???
çà me gene car un chiffre peut avoir aussi bien 2 chiffres après la virgule que 5 çà dépend.
Sinon pour la sauvegarde tu as raison mais je ne pensais vraiment pas que çà allait me faire ce truc je me suis pas méfié surtout qu'avec le nom du type 'DECIMAL' j'imaginais vraiment pas que çà allait m'enlever les chiffres après la virgule
exact.. étant donné que ce n'est pas une approximation d'un nombre il exige que l'on indique une précision. Tout dépend de l'utilisation que tu en fais. Ci c'est monétaire, je crois que 4 décimales, c'est assez.

Avoir su que tu avais des données je t'aurais recommander le backup avant... mais c'est trop tard..

si tu veux remettre des chiffres apres le point décimale, j'ai une petite fonction de random qui pourrait faire!!!
Luc Raymond est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h46.


 
 
 
 
Partenaires

Hébergement Web