Aller au contenu

Détection d'entier


yep

Sujets conseillés

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é par yep
Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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".

Lien vers le commentaire
Partager sur d’autres sites

j'avais lu aussi le manuel php.net :P 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é par yep
Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

j'avais lu aussi le manuel php.net :P 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).

Lien vers le commentaire
Partager sur d’autres sites

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 :lol:) :

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,

 /**
* 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))));
}

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines plus tard...

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 :(

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...