Soyez le premier à donner votre avis sur cette source.
Snippet vu 8 992 fois - Téléchargée 769 fois
function is_prime($_nombre) { if(((int) $_nombre === $_nombre ) && $_nombre > 1) { //Calcul de la racine du nombre $sqrt = sqrt($_nombre); //Si le nombre est multiple de 2 if($_nombre % 2 == 0) { return false; } //Si la racine du nombre est entière elseif((int)$sqrt === $sqrt) { return false; } //On vérifie que la division de tous les nombres compris entre 3 et la racine est entière for($i = 3; $i < $sqrt; $i+=2) { //Si la division est entière if((int) ($_nombre/$i) === $_nombre) { return false; break; } } //Alors le nombre est premier return true; } //Hors limite de PHP else { return '(Attention le resultat est faux : veuillez entrer un entier compris entre 2 et '.PHP_INT_MAX.') '; } }
La fonction dit que 9 n'est pas premier parce que le test sur $sqrt est fait avec === et pas ==.
alors petit rajout à faire histoire de ne pas perdre du précieux temps de calcul : il faut rajouter une condition avant la boucle for (j'ai fait la même erreur dans mon exemple que j'ai rectifié dans mon dernier commentaire) car il ne sert à rien de rentrer dans la boucle for si $_nombre est pair ou un carré...
je te conseil donc de rassembler les conditions précédente dans un if(condition1 || condition2) suivi d'un else{for...
voilà c'est une petite optimisation non négligable pour un benchmark future ;)
en tout cas merci pour cette contribution et n'hésite pas à venir poster sur Codes-Sources : une source est toujours améliorable et tu pourras ainsi apprendre beaucoup de petites choses :-)
voilou amusez vous bien
pour ma part le fait que tu ne te rends même pas compte que ta fonction retournera une valeur fausse si tu dépasse le PHP_INT_MAX (cf ton screen exemple) est une faute impardonnable...
pour ma part je suis pour le retrait de cette source si l'auteur ne fait pas un effort de réflexion et correction sur celle-ci (au minimum reprends ma fonction que tu réécris à ta façon ça ne me gêne pas...)
enfin tu comprendras peut être mieux la grosse erreur que je te reproche comme ça :
en php le $_nombre est un int signé tant que tu rentre un nombre au format int inférieur à PHP_INT_MAX, si tu dépasse PHP_INT_MAX le nombre est alors enregistré en float (exemple : $_nombre=2038313198765657683 sera enregistré en valeur approchée float égale à 2.0E19 sur une machine 32bits), au début de ta fonction tu fais if(is_int($_nombre)){...}else{return false} ce qui retournera false pour toute valeur suppérieur à PHP_INT_MAX et donc sur un serveur 32bits 32416190071 sera retourné non premier alors qu'il l'est belle et bien...
de plus tu es fière de ton benchmark sur tes temps de calcul (sans effectuer d'optimisation) mais sache qu'ils sont totalement faux : 4, 7 et 31 sont plus que rapide à calculer... et ton 999999999999992 lui n'est pas du tout calculté car considéré comme float... donc oui ton code et très rapide mais totalement faux car pour 32416190071 il sera aussi très rapide mais donnera une réponse erroné...
pour ce qui veulent tester :
<?php
function nombre_premier($_nombre)
{
if(is_int($_nombre) && $_nombre>1)
{
$sqrt = sqrt($_nombre);
if (is_int($sqrt) || is_int($_nombre/2))
{
return false;
}
for($i = 3; $i < $sqrt; $i=$i+2)
{
if(is_int($_nombre/$i))
{
return false;
break;
}
}
return true;
}
else
{
echo "(Attention le resultat est faux : veuillez entrer un entier compris entre 2 et ".PHP_INT_MAX." !!!) ";
}
}
?>
<?php echo nombre_premier(4)? 'PREMIER' : 'PAS PREMIER'; ?>
<?php echo nombre_premier(7)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(11)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(23)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(24)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(31)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(179430059)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(32416190071)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(2038313183)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(-31)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(4.89)? 'PREMIER' : 'PAS PREMIER';; ?>
<?php echo nombre_premier(974365496326392643269543)? 'PREMIER' : 'PAS PREMIER';; ?>
PS : pour la compréhention : dans le code j'ai "if(is_int($_nombre) && $_nombre>1)" car comme indiqué le $_nombre est un int signed... j'exclus donc tout ce qui se trouve <1 afin de ne pas rentrer dans la boucle pour rien en cas de nombre négatif et j'exclus au passage les 2 cas particulier de 0 et 1...
voilà cette exemple peut être utilisé comme support méthodologique pour un cours future ;-)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.