/** DEBUT BIGINT addition(BIGINT, BIGINT); DEBUT **/
BIGINT addition(BIGINT nb1, BIGINT nb2) {
    BIGINT resultat;
    int tmp;
    unsigned int retenue = 0;

    initListe(&resultat);

    /// Gestion du signe du résultat ///
    if(nb1.signe == MOINS && nb2.signe == PLUS) {
        nb1.signe = PLUS;
        resultat = soustraction(nb1, nb2);
        resultat.signe = MOINS;
        return resultat;
    } else if (nb1.signe == PLUS && nb2.signe == MOINS) {
        nb2.signe = PLUS;
        return resultat = soustraction(nb1, nb2);
    } else if(nb1.signe == MOINS && nb2.signe == MOINS) {
        resultat.signe = MOINS;
        nb1.signe = PLUS;
        nb2.signe = PLUS;
    }

    while(!listeVide(nb1) && !listeVide(nb2)) {
        tmp = nb1.fin->valeur + nb2.fin->valeur + retenue;
        retenue = tmp / 10;
        empilerListe(&resultat, tmp % 10);
        nb1.fin = nb1.fin->precedent;
        nb2.fin = nb2.fin->precedent;
    }

    /// Necessaire si nb1.nbEl > nb2.nbEl, il faut finir l'addition avec le reste des chiffres de nb1.nbEl ///
    /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire
     ** dans le cas ou nb1.nbEl = nb2.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance
     **/
    while(!listeVide(nb1)) {
        tmp = nb1.fin->valeur + retenue;
        retenue = tmp / 10;
        empilerListe(&resultat, tmp % 10);
        nb1.fin = nb1.fin->precedent;
    }

    /// Necessaire si nb2.nbEl > nb1.nbEl, il faut finir l'addition avec le reste des chiffres de nb2.nbEl ///
    /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire
     ** dans le cas ou nb2.nbEl = nb1.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance
     **/
    while(!listeVide(nb2)) {
        tmp = nb2.fin->valeur + retenue;
        retenue = tmp / 10;
        empilerListe(&resultat, tmp % 10);
        nb2.fin = nb2.fin->precedent;
    }

    /// Ajout de la retenue de fin, si elle existe. Exemple 99 + 10 = 1 retenue et 09 => 109 //
    if(retenue) empilerListe(&resultat, 1);

    nettoyerNb(&resultat);

    return resultat;
}
Exemplo n.º 2
0
void CommandeManager::calculer(QString& chaine) throw(LogMessage){
    QStringList liste = chaine.split(' ',QString::SkipEmptyParts);
    for(QStringList::Iterator it = liste.begin();it!=liste.end();++it){
        QString current = *it;
        if(current.contains(QRegExp("'.*"))){
            QString expr="";
            do{
                expr+=current;
                expr+=" ";
                it++;
                current = *it;
            }
            while(!current.contains(QRegExp(".*'")));
                expr+=current;
                _pile->empilerExpression(expr);
        }
        else if(current.contains(QRegExp("^\\+$")))
            addition();
        else if(current.contains(QRegExp("^\\-$")))
            soustraction();
        else if(current.contains(QRegExp("^\\*$")))
            multiplication();
        else if(current.contains(QRegExp("^/$")))
            division();
        else{
            try{
                _pile->empilerConstante(_factory.getConstante(current));
            }
            catch(LogMessage& msg){
                throw;
            }
        }
    }
}
Exemplo n.º 3
0
Solutions resoudre_second_degre(Complexe b, Complexe c) {
	Complexe quatre_c = {c.re * 4, c.im *4}; 
	Complexe moins_b = {- b.re, - b.im};
	Complexe deux_a = {2, 2};

	Complexe delta = sqrt(soustraction(multiplication(b,b), quatre_c));
	Complexe z1;
	Complexe z2;
	if (delta.re == 0 && delta.im == 0) {
		Complexe p = 
		z1 = division(moins_b, deux_a);
		z2 = z1;
	} else {
		z1 = division(addition(moins_b, delta), deux_a);
		z2 = division(soustraction(moins_b, delta), deux_a);
	}
	Solutions s = {z1, z2};
	return s;
}
Exemplo n.º 4
0
char	*modulo(char *base, char *operators, char *expr1, char *expr2)
{
  char	tmp[2];

  tmp[0] = base[1];
  tmp[1] = '\0';
  while (is_sup(base, expr1, expr2))
    {
      my_strcpy(expr1, soustraction(base, operators, expr1, expr2));
    }
  return (expr1);
}
/** DEBUT BIGINT divisionScolaire(BIGINT, BIGINT); DEBUT **/
BIGINT divisionScolaire(BIGINT nb1, BIGINT nb2) {
    BIGINT resultat, ligne;
    BIGINT tmp;

    initListe(&resultat);
    initListe(&ligne);

    /// Variable pour vidage mémoire des calculs intermédiaires ///
    initListe(&tmp);

    /// Gestion du signe du résultat ///
    resultat.signe = nb1.signe * nb2.signe;

    nb1.signe = PLUS;
    nb2.signe = PLUS;

    if(comparer_nb(nb1, nb2) == INF) {
        empilerListe(&resultat, 0);
        return resultat;
    } else if(comparer_nb(nb1, nb2) == EGAL) {
        empilerListe(&resultat, 1);
        return resultat;
    } else if(nb2.debut->valeur == 0 && nb2.nbEl == 1) {
        /// Impossible de diviser par zero ///
        return;
    }

    while(!listeVide(nb1)) {
        insererFin(&ligne, 0);
        ligne.fin->valeur = nb1.debut->valeur;
        insererFin(&resultat, 0);

        nettoyerNb(&ligne);

        while(comparer_nb(ligne, nb2) >= EGAL) {
            resultat.fin->valeur += 1;
            tmp = soustraction(ligne, nb2);

            viderListe(&ligne);

            ligne = tmp;
        }
        nb1.debut = nb1.debut->suivant;
    }

    nettoyerNb(&resultat);

    return resultat;
}
Exemplo n.º 6
0
/* Subtraction of any number of matrices */
Ref sub_call(ref_list args){
	
	if (args->length < 1 ) {
		set_err(EMISSARG, "need at least one argument");
		return NULL;
	}

	if (arg_isMatrix(args->list[0]) == false) return NULL;
		
	Matrix m = CAST_REF2MATRIX(args->list[0]);

	Matrix sub = copyMatrix(m);
	if (sub == NULL) return NULL;

	unsigned int i;
	for (i = 1; i < args->length; i++){
		
		
		if (arg_isMatrix(args->list[i]) == false) goto error;
		m = CAST_REF2MATRIX(args->list[i]);

		if (m->nrows != sub->nrows || m->ncols != sub->ncols) {
			set_err(EMXDIM,"dimensions don't match");
			goto error;
		}

		Matrix tmp = soustraction(sub, m);
		if (tmp == NULL ) goto error;

		dropMatrix(sub);
		sub = tmp;
	}
    
	/* Return a reference */
	Ref r = new_vref(NULL, sub, MATRIX);
	if (r == NULL) dropMatrix(sub);

	return r;
error:
	dropMatrix(sub);
	return NULL;
}
Exemplo n.º 7
0
char	*division(char *base, char *operators, char *expr1, char *expr2)
{
  char	*res;
  char	tmp[2];

  tmp[0] = base[1];
  tmp[1] = '\0';
  if ((res = malloc(sizeof(*res) * my_strlen(expr1) + my_strlen(expr2) + 1)) == 0)
    return (NULL);
  res[0] = base[0];
  res[1] = '\0';
  if (((indice_in_base(base, expr2[0]) == 1)) && (my_strlen(expr2) == 1))
    return (expr1);
  while (is_sup(base, expr1, expr2))
    {
      my_strcpy(expr1, soustraction(base, operators, expr1, expr2));
      my_strcpy(res, addition(base, res, tmp));
    }
  return (res);
}
Exemplo n.º 8
0
char *modulo(char *base, char  *operators,char *expr1,char *expr2)
{
  char tmp[2];

  tmp[0] = base[1];
  tmp[1] = '\0';
  while (is_sup(base, expr1, expr2))
    {
      my_strcpy(expr1, soustraction(base, operators, expr1, expr2));
    }
  int	nb;
  int   nb2;
  int   nb3;
  int   nb4;
  int   nb5;
  int   nb6;

  nb = 3%1;
  nb2 = 2%4;
  nb3 = -4%2;
  nb4 = 4%-2;
  nb5 = 2%6;
  nb6 = -4%-4;
  my_putstr("\n 3%1 :: ");
  my_put_nbr(nb);
  /*  my_putstr("\n  2%4;");
  my_put_nbr(nb2);
  my_putstr("\n  -4%2;   ");
  my_put_nbr(nb3);
  my_putstr("\n  4%-2;   ");
  my_put_nbr(nb4);
  my_putstr("\n  2%6;    ");
  my_put_nbr(nb5);
  my_putstr("\n  -4%-4  ");
  my_put_nbr(nb6);*/
  my_putstr("FIN::::::::");
  return (expr1);
}
Exemplo n.º 9
0
/**
 * Entrée d'une commande (STDIN) et retour d'une réponse appropriée (STDOUT).
 * Retourne -1 lors d'une demande de quitter le programme, ou 0 si on continue.
 *
 * Invite l'utilisateur à entrer des commandes au format postfixe (ex: 3 2 + 5 * =a).
 */
int traitement_commande() {
    printf("> ");
    
    char* entree = entreeDynamique(stdin);
    
    if(entree == NULL) {
        printf("Pas assez de mémoire pour allouer l'entrée.\n");
        return 0;
    }
    
    if(strcmp(entree, "\0") == 0) {
        // Si l'utilisateur quitte ou entre une ligne vide.
        free(entree);
        
        return -1;
    }
    
    // Les différentes parties sont séparées par des espaces.
    char* partie = strtok(entree, " ");
    
    // Pile des commandes entrées, une fois exécutées.
    pile* commandes = malloc(sizeof(pile));
    
    if(commandes == NULL) {
        printf("Entrée invalide. La mémoire maximale a été dépassée.\n");
        free(entree);
        
        return 0;
    }
    
    pile_init(commandes);
    
    do {
        if(strcmp(partie, "+") == 0 || strcmp(partie, "-") == 0 || strcmp(partie, "*") == 0) {
            if(pile_count(commandes) >= 2) {
                num* r;
                
                num* b = pile_pop(commandes);
                num* a = pile_pop(commandes);
                
                if(strcmp(partie, "+") == 0) {
                    r = addition(a, b, a->positif, b->positif);
                } else if(strcmp(partie, "-") == 0) {
                    r = soustraction(a, b, a->positif, b->positif);
                } else if(strcmp(partie, "*") == 0) {
                    r = multiplication(a, b);
                }
                
                if(r == NULL) {
                    printf("Mauvais calcul !\n");
                    
                    superFree(a);
                    superFree(b);
                    
                    free(entree);
                    free(commandes);
                    
                    return 0;
                }
                
                pile_push(commandes, r);
            } else {
                printf("Erreur: il manque une entree pour faire une operation !\n");
                
                free(entree);
                free(commandes);
                
                return 0;
            }
        } else if(partie[0] == '=' && strlen(partie) == 2 && partie[1] >= 'a' && partie[1] <= 'z') {
            // Assignation de variable, on assigne et on continue comme si de rien n'était.
            
            if(pile_count(commandes) > 0) {
                variables[(int) partie[1] % 32] = pile_peek(commandes);
            } else {
                printf("Que voulez-vous assigner ? Il manque quelque chose...\n");
                
                free(entree);
                free(commandes);
                
                return 0;
            }
        } else if(strlen(partie) == 1 && partie[0] >= 'a' && partie[0] <= 'z') {
            // Variable, on met sa valeur dans la pile d'opérations.
            
            if(variables[(int) partie[0] % 32] != NULL) {
                pile_push(commandes, variables[(int) partie[0] % 32]);
            } else {
                printf("La variable '%c' n'est pas encore définie.\n", partie[0]);
                
                free(commandes);
                free(entree);
                
                return 0;
            }
        } else {
            int est_un_nombre = 1;
            int i = 0;
                                    
            while(i < strlen(partie)) {
                if(partie[i] < '0' || partie[i] > '9') {
                    est_un_nombre = 0;
                    
                    break;
                }
                
                i++;
            }
            
            if(est_un_nombre == 1) {
                // Valeur, on la met dans un nombre à précision infinie et on met sa référence dans la pile.
                num* valeur = malloc(sizeof(num));
                
                if(valeur == NULL) {
                    printf("Entrée invalide. La mémoire maximale a été dépassée.\n");
                    
                    free(entree);
                    free(commandes);
                    
                    return 0;
                }
                
                strToBigNum(partie, valeur);
                
                pile_push(commandes, valeur);
            } else {
                // Caractère non-valide.
                printf("Les éléments doivent tous être des variables (a-z, minuscule), des opérateurs ou bien des valeurs positives entières.\n");
                
                return 0;
            }
        }
    } while(partie = strtok(NULL, " "));
    
    if(partie != NULL) {
        free(partie);
    }
   
    if(entree != NULL) {
        free(entree);
    }
    
    if(pile_count(commandes) == 1) {
        printNum(pile_pop(commandes));
    } else {
        printf("Erreur de syntaxe, veuillez completer vos calculs !\n");
    }
        
    free(commandes->data);
    free(commandes);
    
    return 0;
}
Exemplo n.º 10
0
/**
 * Opération d'addition.
 */
num* addition(num* a, num* b, int ancien_a_positif, int ancien_b_positif) {
    if(a->positif == 0 && b->positif == 1) {
        a->positif = 1;
        
        return soustraction(b, a, ancien_b_positif, ancien_a_positif); // Vu que a et b sont inversés, leur "ancien_a_positif" et "ancien_b_positif" aussi.
    }

    if(a->positif == 1 && b->positif == 0) {
        b->positif = 1;
        
        return soustraction(a, b, ancien_a_positif, ancien_b_positif);
    }
    
    if(a->positif == 0 && b->positif == 0) {
        b->positif = 1;
        
        return soustraction(a, b, ancien_a_positif, ancien_b_positif);
    }
    
    setupNombres(a, b);

    cell* cA = a->nombre;
    cell* cB = b->nombre;

    if(!cA || !cB) {
        return NULL;
    }

    cell* result = malloc(sizeof(cell));
    memcheck(result);
    
    num* r = malloc(sizeof(num));
    memcheck(r);
    
    r->longueur = 0;

    int fini = 0;
    int intermediaire = 0;
    int carry = 0;

    cell* newUnit = NULL;
    r->nombre = result;
    
    while(!fini) {
        fini = cA->suivant == NULL && cB->suivant == NULL;

        intermediaire = cA->chiffre + cB->chiffre + carry;

        if(intermediaire > 9) {
            carry = 1;
            intermediaire -= 10;
        } else {
            carry = 0;
        }

        result->chiffre = intermediaire;
        
        if(!fini) {
            // Ajustement des pointeurs pour le prochain round si pertinent.
            newUnit = malloc(sizeof(cell));
            memcheck(newUnit);
            
            newUnit->suivant = NULL;
            newUnit->precedent = result;

            result->suivant = newUnit;
            result = newUnit;
        }

        cA = cA->suivant;
        cB = cB->suivant;
        r->longueur++;
    }
    
    if(newUnit == NULL) {
        // Cas particulier où on n'a pas de "carry" et un seul digit dans chaque opérande (ex : 2+2).
        result->suivant = NULL;
        r->dernier = result;
    } else {
        newUnit->suivant = NULL;
        r->dernier = newUnit;
    }

    if(carry) {
        cell* carryCell = malloc(sizeof(cell));
        memcheck(carryCell);

        carryCell->chiffre = carry;
        carryCell->precedent = result;
        
        result->suivant = carryCell;
        carryCell->suivant = NULL;
        
        r->dernier = carryCell;
        r->longueur++;
    }

    r->positif = 1;
    
    a->positif = ancien_a_positif;
    b->positif = ancien_b_positif;
    
    return r;
}
Exemplo n.º 11
0
/** DEBUT BIGINT multiplicationKaratsuba(BIGINT, BIGINT); DEBUT **/
BIGINT multiplicationKaratsuba(BIGINT nb1, BIGINT nb2) {
    BIGINT x0, x1, y0, y1, p0, p1, p2, resultat;
    BIGINT tmp, tmp2;
    int m, i, signe_nb1, signe_nb2;

    signe_nb1 = nb1.signe;
    signe_nb2 = nb2.signe;
    nb1.signe = PLUS;
    nb2.signe = PLUS;
    nb1.signe = PLUS;
    nb2.signe = PLUS;

    initListe(&resultat);

    /// Variables pour calculs intermédiaires ///
    initListe(&x0);
    initListe(&x1);
    initListe(&y0);
    initListe(&y1);
    initListe(&p0);
    initListe(&p1);
    initListe(&p2);

    /// Variables pour vidage mémoire des calculs intermédiaires ///
    initListe(&tmp);
    initListe(&tmp2);

    /// On enlève les 0 devant nb1 et nb2, car la taille du nombre est importante dans l'execution de l'algorithme de karatsuba ///
    nettoyerNb(&nb1);
    nettoyerNb(&nb2);

    /// m = milieu du plus grand nombre. Exemple : 9828839 => m = 4, 192893 => m = 3 ///
    m = (max_element(nb1, nb2) + 1) / 2;

    /// Creation de x0 et x1, dont nb1 = x1 * B^m + x0 ///
    if(nb1.nbEl <= m) {
        x0 = clone(nb1);
        empilerListe(&x1, 0);
    } else {
        for(i = 0; i < m; i += 1) {
            empilerListe(&x0, nb1.fin->valeur);
            nb1.fin = nb1.fin->precedent;
        }
        while(!listeVide(nb1)) {
            empilerListe(&x1, nb1.fin->valeur);
            nb1.fin = nb1.fin->precedent;
        }
    }

    /// Creation de y0 et y1, dont nb2 = y1 * B^m + y0 ///
    if(nb2.nbEl <= m) {
        y0 = clone(nb2);
        empilerListe(&y1, 0);
    } else {
        for(i = 0; i < m; i += 1) {
            empilerListe(&y0, nb2.fin->valeur);
            nb2.fin = nb2.fin->precedent;
        }
        while(!listeVide(nb2)) {
            empilerListe(&y1, nb2.fin->valeur);
            nb2.fin = nb2.fin->precedent;
        }
    }

    /// On enlève les 0 devant x0, x1, y0 et y1, car la taille du nombre est importante dans l'execution de l'algorithme de karatsuba ///
    nettoyerNb(&x0);
    nettoyerNb(&x1);
    nettoyerNb(&y0);
    nettoyerNb(&y1);

    /// Calculs d'après l'algorithme de karatsuba (voir description) ///
    p0 = multiplication(x0, y0);
    p2 = multiplication(x1, y1);

    tmp = addition(x0, x1);
    tmp2 = addition(y0, y1);

    p1 = multiplication(tmp, tmp2);

    viderListe(&tmp);
    viderListe(&tmp2);
    viderListe(&x0);
    viderListe(&x1);
    viderListe(&y0);
    viderListe(&y1);

    tmp = soustraction(p1, p2);

    p1 = soustraction(tmp, p0);

    viderListe(&tmp);

    puissancede10(&p1, m);
    puissancede10(&p2, (m * 2));

    tmp = addition(p0, p2);
    resultat = addition(p1, tmp);

    viderListe(&tmp);

    /// Gestion du signe du résultat ///
    resultat.signe = signe_nb1 * signe_nb2;

    return resultat;
}
Exemplo n.º 12
0
Ref speedtest_cmd(ref_list args){

	puts("Starting test...");

	bool doplot = true; keepgoing = true; 

	Fun f = (Fun) args->list[0]->inst;
	int min = (int) (*(float*) ((Var)args->list[1]->inst)->val);
	int max = (int) (*(float*) ((Var)args->list[2]->inst)->val);
	int step = (int) (*(float*) ((Var)args->list[3]->inst)->val);
		
	if ( min > max || step == 0) {
		set_err(ENOVAL, "infinite tests are not allowed");
		return NULL;
	}

	/* Optional parameter */
	if (args->length > 4 && cmptype_ref(FLOAT, args->list[4])) {
		int countdown = (int) (*(float*) ((Var)args->list[4]->inst)->val);
		signal(SIGALRM, stop_speedtest);
		alarm(countdown);
	} 
	
	
	/* Points list */	
	clock_t* y_time = malloc (sizeof(clock_t) * (max-min)/step + 1);
	int* x_size = malloc (sizeof(int) * (max-min)/step + 1);
	if (y_time == NULL || x_size == NULL){
		free(x_size); free(y_time);
		return NULL;
	}

	
	int i,j;
	for ( i = min, j=0; i <= max && keepgoing ; i += step, j++){
		
		/* Generate matrices. 
		   Note: they don't need to be initialized 
		*/
		Matrix m1 = newMatrix(i,i), m2 = newMatrix(i,i), ret = NULL;
		float* f1 = malloc(sizeof(float));
		if (m1 == NULL || m2 == NULL || f1 == NULL){ 
			perror("");
			keepgoing = false; doplot = false;
		}

		/* Start test */
		clock_t start = clock();

		if (f->fun == mult_call) {
			ret = multiplication(m1,m2);

		} else if ( f->fun == sub_call) {
			ret = soustraction(m1,m2);

		} else if (f->fun == addition_call){
			ret = addition(m1,m2);

		} else if (f->fun == transpose_call){
			ret = transpose(m1);	

		} else if (f->fun == determinant_call){
			determinant(m1, f1);	

		} else if (f->fun == invert_call){
			invert(m1,&ret);

		} else if (f->fun == rank_call ){
			rank(m1);
		} else {
			printf("Sorry...cannot test this function\n");
			keepgoing = false; doplot = false;
		}
		
		
		/* Finish test */
		clock_t end = clock();
	
		/* Store result */	
		x_size[j] = i; y_time[j] = end-start;
		
		dropMatrix(m1);
		dropMatrix(m2);
		dropMatrix(ret);
		free(f1);
	}

	alarm(0); // Remove countdown

	if (doplot == true) plot(args->list[0]->name, x_size, y_time, j);

	free(x_size); free(y_time);

	return NO_REF;
}