Version complète: sur le forum Webmaster Hub : Détection d'entier
Webmaster Hub > Création et exploitation de Sites Internet > Les langages du Net > PHP
yep
Bonjour à tous,
j'ai un petit problème de détection d'un entier.

CODE
$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 ?
TheRec
Bonjour,

Il y a deux raisons à cela... La première dépend de ta version PHP :
CITATION
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 :
CODE
echo gettype($c);

Cela affichera le type de la variable.
yep
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
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
j'avais lu aussi le manuel php.net tongue.gif 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
TheRec
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
CITATION(yep @ vendredi 21 juillet 2006, 16h57) *
j'avais lu aussi le manuel php.net tongue.gif 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
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 laugh.gif) :
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.

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
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,
CODE
/**
* 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
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 sad.gif
TheRec
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.
stefane2008
merci beaucoup a_thumbsup_20.gif a_thumbsup_20.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.