30

Pour le moment je ne vise pas un cas, mais une apps de calcul pouvant travailler avec des entiers de taille inf etc.. (c'est pour cela que mes fonctions font des malloc(sizeof(double)) qui sera ensuite modifié) qui a aussi un ploteur (2D uniquement, c pas ce qu'il y a de plus dur a faire...) une pile (RPN normalement, d'ailleurs la validité de l'expression sera évaluée au cours du calcul)) et pretty print. Ca fait bcp c pour ca que je promet rien, pour le moment je me familliarise avec un algo d'evaluation d'expression.
En revanche il pourra accepter 2*x+1 | x=3 ou 2*x+1 -> f(x) (d'ailleur il le gere deja en interne).

31

32

intéressant tout ça merci celà va m'aider... wink

33

En effet, c'est simple et clair.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

34

35

bon voilà ca marchetongue #include <tigcclib.h> #include "TinyCalc.h" float Operator(float dNbr1, char Op, float dNbr2) {      switch(Op)      {      case '+':           return dNbr1+dNbr2;      case '-':           return dNbr1-dNbr2;      case '/':           return dNbr1/dNbr2;      case '*':      default:           return dNbr1*dNbr2;      } } unsigned short PriorityOp(char Op) {      switch(Op)      {           case '+': // binaire ...           case '-':                return 12;           case '*':           case '/':           default:                return 13;      } } float EvalRPNExpr(sExpression *psExpression) {      sElement *pTmp = psExpression->pTokenizeExpr;      float *pTmp2 = (float*)malloc(psExpression->uSize*sizeof(float));      float x,y;      while(pTmp->uType != END)      {           if (pTmp->uType == 'O')           {                x = *(--pTmp2);                y = *(--pTmp2);                *pTmp2++ = Operator(x,pTmp->Op,y);           }           else                *pTmp2++ = *(float*)pTmp->pValue;           pTmp++;      }      return *--pTmp2; } sElement *AlgToRPN(sElement *psElement, unsigned short uN) {      unsigned short ipsElementTmp=0, ipsElementFinal=0;      sElement *psElementTmp, *psElementFinal;      unsigned short uPriority=0; // Last priority of the tmp stack            if( !(psElementTmp = (sElement*)malloc(sizeof(sElement)*uN)))           return NULL;      if( !(psElementFinal = (sElement*)malloc(sizeof(sElement)*uN)))      {           free(psElementTmp);           return NULL;      }            while(psElement->uType != END)      {           switch(psElement->uType)           {                case 'I':                case 'R':                case 'P':                     memcpy(&psElementFinal[ipsElementFinal++],psElement,sizeof(sElement));                     break;                case 'O':                     if (uPriority <= PriorityOp(psElement->Op)) // push on Tmp Stack                     {                          memcpy(&psElementTmp[ipsElementTmp++],psElement,sizeof(sElement));                          uPriority = PriorityOp(psElement->Op);                                              }                     else  // Pop and push on final stack                     {                          memcpy(&psElementFinal[ipsElementFinal++],&psElementTmp[--ipsElementTmp],sizeof(sElement));                          psElement--;  // repeat while uPriority > PriorityOp(psElement->Op)                                                   if (ipsElementTmp == 0)                               uPriority = 0; // it's the lowest priority                          else                               uPriority = PriorityOp(psElementTmp->Op);                                                   }                     break;                case 'F':                case '(':                     memcpy(&psElementTmp[ipsElementTmp++],psElement,sizeof(sElement));                     uPriority = 1;                               break;                                                                  case ')':                     if(psElementTmp[ipsElementTmp-1].uType != '(')                     {                          memcpy(&psElementFinal[ipsElementFinal++],&psElementTmp[--ipsElementTmp],sizeof(sElement));                          psElement--;  // repeat while uType != '('                     }                     else                          ipsElementTmp--;                     break;                                    }           psElement++;      }           while (ipsElementTmp--!=0)           memcpy(&psElementFinal[ipsElementFinal++],&psElementTmp[ipsElementTmp],sizeof(sElement));           psElementFinal[ipsElementFinal].uType = END;      free(psElementTmp);      return psElementFinal; } int TokenizeExpr(sExpression *psExpression) {      char *pExpr = psExpression->pExpr;      sElement *pElement1,*pElement = (sElement*)malloc(sizeof(sElement)*100);      unsigned short size = 100;      unsigned short uN = 0;      void *pValue = NULL;      char uType,Op='N',Name[9];            if (pElement==NULL)           return 1;             while(*pExpr != '\0' && *pExpr != STO && *pExpr!= OR)      {           // Checking Ram space           if ( uN == size -1) // -1 for the END flags           {                size += 100;                pElement1 = (sElement*)realloc(pElement,sizeof(sElement)*size);                if (pElement1 ==NULL)                {                     free(pElement);                     return 1;                }                pElement = pElement1;           }                      // it's a number           if (*pExpr>='0' && *pExpr<='9')           {                pValue = (float*)malloc(sizeof(float));                uType = INTEGER;                               float IntValue = 0;                float dDec = 10;                while ((*pExpr>='0' && *pExpr <='9'))                     IntValue = IntValue*10 + *pExpr++ - '0';                if (*pExpr=='.')                {                     uType = REAL;                     pExpr++;                     dDec = 10;                     while ((*pExpr>='0' && *pExpr <='9'))                     {                          IntValue = IntValue + (*pExpr++ - '0')/dDec;                          dDec*=10;                     }                }                               *(float*)pValue = IntValue;           }           else           // It's an operator           if ( *pExpr == '+' || *pExpr == '-' || *pExpr == '/' || *pExpr == '*' || *pExpr == '^')           {                uType = OPERATOR;                pValue = malloc(sizeof(char));                Op = *pExpr++;           }           else           // It's a function or a parameter           if(     (*pExpr >='a' && *pExpr<='z') ||     (*pExpr>='A' && *pExpr<='Z'))           {                int i=0;                while (     (*pExpr >='a' && *pExpr <='z')                           ||     (*pExpr >='A' && *pExpr <='Z')                          ||     (*pExpr >='0' && *pExpr <='9'))                     Name[i++] = *pExpr++;                // It's a function                if (*pExpr == '(' )                {                     uType = FUNCTION;                     pExpr++;                }                // It's a parameter                else                uType = PARAMETER;                Name[i]=0;           }           // else brackets...           else if (*pExpr == '(' )           {                uType = BRACKETSOPEN;                pExpr++;           }           else if (*pExpr == ')' )           {                uType = BRACKETSCLOSE;                pExpr++;           }           else if (*pExpr == ' ' && (*(pExpr+1) == STO || *(pExpr+1) == OR))                break;           // Error                else           {                free(pElement);                return (pExpr - psExpression->pExpr + 1);           }                strcpy(pElement[uN].Name,Name);           pElement[uN].pValue = pValue;           pElement[uN].uType = uType;           pElement[uN].Op = Op;           uN++;      }       pElement[uN].uType = END;      psExpression->pTokenizeExpr = AlgToRPN(pElement,uN);      psExpression->uSize = uN;      free(pElement);      return 0; } void DisplayTokenizedExpr(sExpression *psExpression) {      sElement *pElement = psExpression->pTokenizeExpr;      while(pElement->uType != END)      { //          printf("Type : %c \n",pElement->uType);           if (pElement->uType != BRACKETSOPEN && pElement->uType != BRACKETSCLOSE)           {                if (pElement->uType == 'I' || pElement->uType == 'R' )                     printf("Value : %f \n",*(float*)(pElement->pValue));                else if (pElement->uType == 'O' )                     printf("Operator : %c \n",pElement->Op);                if (pElement->uType == PARAMETER || pElement->uType == FUNCTION)                     printf("Name  : %s \n",pElement->Name);           }           pElement++;      } }    void _main(void) {      char Buffer[1000];      sExpression Expr;      Expr.pExpr = Buffer;      while(1)      {           puts("Enter expression : ");           gets(Buffer);           puts("\n");           if (strcmp(Buffer,"exit")==0)                break;            TokenizeExpr(&Expr);           DisplayTokenizedExpr(&Expr);           printf("Resultat %f \n",EvalRPNExpr(&Expr));      } }
Il n'y a plus rien de recursif.. et l'evaluation se fait par la simple fonction:
float EvalRPNExpr(sExpression *psExpression)
{
	sElement *pTmp = psExpression->pTokenizeExpr;
	float *pTmp2 = (float*)malloc(psExpression->uSize*sizeof(float));
	float x,y;
	while(pTmp->uType != END)
	{
		if (pTmp->uType == 'O')
		{
			x = *(--pTmp2);
			y = *(--pTmp2);
			*pTmp2++ = Operator(x,pTmp->Op,y);
		}
		else
			*pTmp2++ = *(float*)pTmp->pValue;
		pTmp++;
	}
	return *--pTmp2;
}

36

merci pour ces renseignements je n'ai pass tout compris mais je vais me pencher dessus. au cas où j'espere que tu pourras repondre a mes questions kiss

37

Pas de probleme.

Bon alors nouvelle version et derniere pendant un certain temps (stage + profitage de vacancestongue)
Ca gere quoi?
+-*/¨ masi pas le - unaire, j'ai eu la flemme de faire un debug.
les fonctions: sqrt,factorial,abs,acos,acosh,asin,asinh,atan,atanh,ceil,cos,cosh,exp,floor,log,log10,sin,sinh,sqrt,tan,tanh (c tout je crois).
ca gere les constantes en interne (j'ai pas eu le temps de programmer le -> ou | qui de toute maniere ne sont pas reprensenté en RPN.
ca tokénises le expr, pour accelerer le calcul pour le ploteur.
reste a faire:
Toutes l'arithmétique sur un nouveau type de donné (celui de pedrom? ou un encore plus de ouftongue)
Gestion des constantes a travers l'interface (facile)
Gestion des fonctions a travers l'interface (facile)
Pile
ploteur
tableur.
et surtout: OPTIMISATION de la reconnaissance des fonctions par table ou dichotomie, parce que là j'ai un peut honte:"

le projet:


il n'y a pas la gestion des erreurs.. ce sera géré par la pile.

38

grr apparrement ma fonction EvalRPN est trop lentesad

39

la lenteur peut aussi venir du malloc, parce que c lent, meme si je met pas de fonction... genre je met 1 comme ecpr ca semble etre lent pour calculer les 240 valeurs pour faire un plot

40

C'est interessant ton truc (post #36), j'étais en train d'essayer de faire exactement la même chose y'a qq jours happy
Mais ça gerait pas les fonctions.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

41

tu as utilisé un arbre ou une pile?

42

Une pile, je suis tombé sur le même principe que celui expliqué sur le lien du post #33, mais j'ai mit du temps pr que ça marche correctement vu que je connaissais aucun algo là-dessus et que j'ai voulu tenter le pifometre :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

43

Ah tiens, j'ai l'impression qu'un truc ne va pas dans ton TinyCalc : Pour "2*(2-3)+4*5-(1+1)" il me retourne -40. Un de ces jours ça m'interesserais que tu m'explique un peu ta méthode, si tu passes sur irc...
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

44

Attention au memory leak.. il y en a pas mal.
je vais regarder pour ton exp

45

hello je n'ai toujours pas compris certaines choses mais bon je n'ai pas non plus eu le temps de m'y pencher vu que je suis sur un autre projet qui ne me passionne pas..

46

tu as une façon bien à toi de coder, et une vision des choses propres à toi...suis tu un algo en particulier ou suis tu ton propre cheminement.
en tout cas il me faudra du temps si je veux adapter certaines choses pour mon prog...

47

C'est corrigé, 2 problemes:
d'une part les opérateur étaient executé a l'inverse: 3-2 au lieu de 2-3.
d'autre part, je ne restaurais pas la priorité lorsque je depilais ')' dans le tmpstack.

48

Pour l'algo, j'ai utilisé l'algo de l'aiguille, mais j'ai choisi de tokeniser les données pour gagner du temps au pretty print et au plotteur.. il y a certzines parties qui sont mal codées (fonction, + evaluation avec maloc a la barbar qui est meme pas desallouer..). Sinon l'algo est respecté a 99% tongue

49

Oué j'ai aussi fait l'aiguille, pour toutes les operations de base je vois comment faire, mais pour les fonctions et les mot clés (conditions, boucles, etc) je sais pas encore comment je vais m'y prendre.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

50

J'espere que tu ne l'as pas mal pris bisoo

51

a quand une conversation jackosking?

52

Mais quelles sont tes questions ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

53

thibaut ?

54

pourquoi tu pourrais me repondre?

55

pose tes questions... happy

56

mon prog ne gere pas les sinus d'un nbre neg(-qqc)

57

sin(-x) = -sin(x)
avatar
;)

58

merci je connais ma trigo simplement je veux que mon prog gere les sin(-x) rage

59

Bah tel que tu le dis, j'ai compris que tu gères déjà sin(x).
Si tu gères sin(x) avec une fonction (les types c'est toi qui vois si tu fais aussi une calculatrice d'entiers infinis ça sera pas double, et unary_neg c'est le - unaire, appliqué à ton format de données)
double my_sin(double x)
{
  if (x < 0)
    return unary_neg(my_sin(-x));
// Ton code de calcul de sin(x) qui existe déjà normalement
}
avatar
;)

60

Bah tel que tu le dis, j'ai compris que tu gères déjà sin(x).
Si tu gères sin(x) avec une fonction (les types c'est toi qui vois si tu fais aussi une calculatrice d'entiers infinis ça sera pas double, et unary_neg c'est le - unaire, appliqué à ton format de données)
double my_sin(double x)
{
  if (x < 0)
    return unary_neg(my_sin(unary_neg(x)));
// Ton code de calcul de sin(x) qui existe déjà normalement
}
avatar
;)