yep Posté 21 Juillet 2006 Posté 21 Juillet 2006 (modifié) Bonjour à tous, j'ai un petit problème de détection d'un entier. $a=27;$b=3;$c = pow($a,1/$b);if(is_int($c)) { echo $c.' est un entier';} else { echo $c.' n\'est pas un entier';} Avec ce code, $c n'est jamais considéré comme un entier. alors que pour cet exemple $c est égal à 3, qui est un entier. Auriez-vous une solution pour que cela fonctionne ? Modifié 21 Juillet 2006 par yep
TheRec Posté 21 Juillet 2006 Posté 21 Juillet 2006 Bonjour, Il y a deux raisons à cela... La première dépend de ta version PHP : En PHP 4.0.6 plus ancien, pow() retournait toujours un nombre à virgule flottante (float), et n'affichait pas d'alerte. Si le calcul est impossible (racine d'un nombre négatif, par exemple), pow() retournait NAN. Mais dans ton cas je pencherais plus sur le fait qu'une des composantes de ton calcul est un nombre à virgule flottante (double ou float en fonction de l'architecture de ton système) provoque cela, pow semble réagir comme cela (en dépit de ce que peux dire le manuel : "Si possible, pow() retourne un entier."). Si les deux composantes de ton calcul sont des entiers, ton test retournera "true" et dans ce cas tu obtiendras la réponse que tu souhaites. Le fait que lorsque tu fasses : echo $c; Tu obtiennes "3", c'est uniquement parce que PHP n'affiche pas les 0 non significatifs par défaut... si tu veux une preuve de cela, utilise la fonction gettype : echo gettype($c); Cela affichera le type de la variable.
yep Posté 21 Juillet 2006 Auteur Posté 21 Juillet 2006 tu m'as déjà bien éclairé, merci. si 'jai bien compris, si $a et $b sont des entiers alors par $c en sera un également?
TheRec Posté 21 Juillet 2006 Posté 21 Juillet 2006 Oui exactement ! Du moins si t'as version PHP est supérieure à 4.0.6, avant et avec cette release "pow" renvoyait toujours une variable à virgule flottante ou NAN (Not a Number). Essaie de mettre $b = 1; en gardant les autres variables telles qu'elles, ta condition sera vérifiée et affichera "27 est un entier".
yep Posté 21 Juillet 2006 Auteur Posté 21 Juillet 2006 (modifié) j'avais lu aussi le manuel php.net la source... et en fait je me suis rendu compte qu'il m'était impossible d'avoir un entier retourné puisque je transmettais une fraction. (le nb) merci toutefois de ton aide Modifié 21 Juillet 2006 par yep
TheRec Posté 21 Juillet 2006 Posté 21 Juillet 2006 Les fractions n'existent pas en PHP ... c'est une opération intermédiaire, une division dont tu obtiens le quotient que tu passes en second paramètre dans la fonction pow.
MarvinLeRouge Posté 21 Juillet 2006 Posté 21 Juillet 2006 j'avais lu aussi le manuel php.net la source...et en fait je me suis rendu compte qu'il m'était impossible d'avoir un entier retourné puisque je transmettais une fraction. (le nb) merci toutefois de ton aide Salut, Si tu cherches juste à savoir si la valeur retournée est une valeur entière, tu pourrais, par exemple, comparer la valeur retournée x avec l'arrondi de cette valeur à l'entier le plus proche round(x).
TheRec Posté 21 Juillet 2006 Posté 21 Juillet 2006 Mouais... c'est relativement fiable, cela dépend d'où est utilisé le script (environnement 32 ou 64 bits, ...), la comparaison de nombres à virgule flottante n'est jamais vraiment fiable... Pour justifier cette remarque je vais citer le manuel PHP (encore... je vous rassure, je lis d'autres truc des fois ) : 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. C'est pourquoi lorsqu'on veut comparer des nombres à virgule flottante on utilise une marge de précision généralement nommée "Epsilon" (lettre grecque) qui dépend de l'environnement en question... Donc, pour vérifier une "égalité" on procèderait ainsi : |nombre1 - nombre2| < epsilon Où epsilon est minime, par exemple : 0.0001 On peut penser que cela n'amène rien car le calcul produit également un nombre à virgule flottante, mais cette précision est utilisée au sein du même système binaire et donc par rapport à celui-ci elle est significative ! Cela peut sembler être du "bricolage", mais c'est la seule possibilité à ma connaissance d'éviter une majorité de problèmes lors de la représentation de nombres à virgule flottante et de leurs comparaisons. C'est un peu hors sujet, mais je tiens juste à préciser cela si tu viens à effectuer des comparaisons sur des nombres à virgule flottante. Ci-après les 3 fonctions que j'utilise généralement, /** * Compare equality of two floats with a presision factor : $epsilon * * @date 2005-04-02 * @param float $first First variable for comparaison * float $second Second variable for comparaison * float $epsilon Small factor to work around the float imprecision * @return bool true = equal, false = not equal */ function floatEqual($first,$second,$epsilon) { return (abs($first - $second) < $epsilon); } /** * Compare two floats to see if $first is greater or equal to $last * * @date 2005-04-02 * @param float $first First variable for comparaison * float $second Second variable for comparaison * float $epsilon Small factor to work around the float imprecision * @return bool true = greater or equal, false = smaller */ function floatGreaterOrEqual($first,$second,$epsilon) { return (floatEqual($first,$second,$epsilon) || (($first > ($second - $epsilon)) && ($first > ($second + $epsilon)))); } /** * Compare two floats to see if $first is lesser or equal to $last * * @date 2005-04-02 * @param float $first First variable for comparaison * float $second Second variable for comparaison * float $epsilon Small factor to work around the float imprecision * @return bool true = lesser or equal, false = greater */ function floatLesserOrEqual($first,$second,$epsilon) { return (floatEqual($first,$second,$epsilon) || (($first < ($second - $epsilon)) && ($first < ($second + $epsilon)))); }
stefane2008 Posté 30 Juillet 2006 Posté 30 Juillet 2006 Bonjour Je vous ai lu avec beaucoup d'interet. Cela dit j'ai un petit probleme avec les decimales - comment faire tester par php ( si un nombre $n a une point en guise de virgule ) ET ( si les decimales qui suivent sont au nombre de 2 ) ? Plus precisement si $n = 125 alors retourne $n = 125.00 ==> avec un point partout si $n = 125.5 alors retourne $n = 125.50 si $n = 125.59 alors retourne $n = 125.59 J'avais pensé aux regex mais bon en fait je cale
TheRec Posté 30 Juillet 2006 Posté 30 Juillet 2006 Bonjour, La fonction number_format devrait faire l'affaire... Tu peux aussi utiliser des fonctions du type sprintf ou printf qui sont plus "compliquée" car elles requièrent un bref apprentissage de la syntaxe de formatage, mais elle sont plus puissantes (elle ne se limitent pas qu'au formatage des nombres). Bonne continuation.
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant