Fonction equation légère

Soyez le premier à donner votre avis sur cette source.

Snippet vu 4 607 fois - Téléchargée 21 fois


Contenu du snippet

Fonction equation en 50 lignes de code. Prend une équation (string $equation) en paramètre (ex.: 5+5*300/2-50) et renvoie le résultat en prenant en compte les priorités, en analysant la chaîne peu importe sa longueur et peu importe les espacements (ex.: 2 + 2 *4 / 4). Je ne voulais pas utiliser eval(), en contexte web, j'aime mieux ne pas activer la fonction dans PHP. Exemple d'utilisation :

->copier/coller code source<-

echo equation("10+2");

Source / Exemple :


<?php
function operation($a,$b,$c) {
   switch($b) {
      case '+': return $a + $c; break;
      case '-': return $a - $c; break;
      case '*': return $a * $c; break;
      case '/': return $a / $c; break;
}   }
function equation($equation) {
$input = str_replace(' ','',trim($equation));
$caracteres = preg_split('//',$input,-1,PREG_SPLIT_NO_EMPTY);
for($i=0;$i<count($caracteres);$i++) {
   if(!is_numeric($caracteres[$i])) {
      $operateurs[].= $caracteres[$i];
      $nb .= ' ';
   } else {
      $nb .= $caracteres[$i];
}   } 
$nombres = explode(' ',$nb);
for($i=0;$i<count($operateurs);$i++) {
   if($operateurs[$i] == "*" || $operateurs[$i] == "/") {
      if($operateurs[$i-1] == "*" || $operateurs[$i-1] == "/") {
         $last = count($nouv_eq) - 1;
         $nouv_eq[$last] = operation($nouv_eq[$last],$operateurs[$i],$nombres[$i+1]);
      } else {
         $nouv_eq[] .= operation($nombres[$i],$operateurs[$i],$nombres[$i+1]);
      }
   } else {
      if($operateurs[$i-1] != "*" && $operateurs[$i-1] != "/") $nouv_eq[] .= $nombres[$i];
      $nouv_eq[] .= $operateurs[$i];
      if($i == count($operateurs)-1) $nouv_eq[] .= $nombres[$i+1];
}   }
for($i=0;$i<count($nouv_eq);$i++) {
   if(!is_int($i / 2)) $nouv_operateurs[] .= $nouv_eq[$i];
   else $nouv_nombres[] .= $nouv_eq[$i];
}
if(count($nouv_operateurs) > 0) {
   for($i = 0;$i<count($nouv_operateurs);$i++) {
      if($i == 0) $rslt = operation($nouv_nombres[0],$nouv_operateurs[0],$nouv_nombres[1]);
      else $rslt = operation($rslt,$nouv_operateurs[$i],$nouv_nombres[$i+1]);
}   }
else {
   $rslt = $nouv_nombres[0];
}
return $rslt;
}
?>

A voir également

Ajouter un commentaire

Commentaires

Messages postés
40
Date d'inscription
mercredi 19 mars 2008
Statut
Membre
Dernière intervention
25 août 2009

Salut à tous.
Je viens de regarder rapidement cette source. Pour répondre aux premiers commentaires je dirai :

Les expression régulière allègeraient peu etre le code mais on y perdrait question performance. Donc après tout dépend de l'utilisation à en faire.

Pour ce qui est des inconnus effectivement cette source porte mal son nom, elle évalu une chaine de caractère mais ne résou en aucun cas des équations.

Sinon elle gère les priorité des opérateurs, elle est rapide. Toutefois elle ne gère pas les divisions par zéros(n'affiche pas d'erreur). Sur le plan programmation il y a deux choses à dire :

1) TU as une variable que tu utilises alors qu'elle n'a pas été définit (Si la configuration du php.ini est bien faite elle t'affichera cette erreur) variable nb ligne 18

2)Au premier tour de boucle tu test une case du tableau non initialisé la case -1. (encore une fois une bonne configuration de php.ini te le diras).

Sinon ta source est pas mal du tout je me suis moi même exercé à faire une fonction de ce type. Elle prend beaucoup plus d'opérateur gére les erreurs mais elle est beaucoup plus lourde. Je t'invite à la regarder : http://www.phpcs.com/codes/EVALUER-EXPRESSION-PARTIR-CHAINE-CARACTERE_50144.aspx

Bonne continuation
Bien Cordialement
TheWeasel47
Messages postés
15
Date d'inscription
dimanche 2 novembre 2008
Statut
Membre
Dernière intervention
27 juin 2011

tu met ou les incinnues? et si racine carrée, tu fait koi? ca marche pas
Messages postés
6063
Date d'inscription
dimanche 13 avril 2003
Statut
Modérateur
Dernière intervention
15 juillet 2011
26
Des expressions régulières capturantes permettent surement d'alléger ce code.

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.