Programmation Avancée en C


tools.h

00001 /**********************************************************
00002  * @file tools.c
00003  * @author Sebastien Varrette <Sebastien.Varrette@imag.fr>
00004  * @date   Mon Apr 10 2006  
00005  *
00006  * Copyright (c) 2006 Sebastien Varrette  (http://www-id.imag.fr/~svarrett/)
00007  *
00008  * @brief  
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023  * 
00024  * Sebastien Varrette                               \n
00025  * <Sebastien.Varrette@imag.fr>                     \n
00026  * University of Luxembourg / ID-IMAG Laboratory    \n
00027  * 162-A avenue de la faiencerie                    \n
00028  * L-1511 Luxembourg, LUXEMBOURG                    \n
00029  */
00030  /********************************************************************************/
00031 
00032 #include <stdio.h>
00033 
00034 /**
00035  * Calcul du pgcd de 2 nombres par l'algorithme d'Euclide
00036  */
00037 int pgcd(int a, int b) {
00038     int e = (a < 0)?-a:a; // Pour assurer des valeurs positives
00039     int f = (b < 0)?-b:b;
00040     int tmp;
00041     if (e == 0) return f;
00042     while (f > 0) {
00043         tmp   = f;
00044         f = e % f; // Calcul de r = a % b
00045         e = tmp;
00046     }
00047     return e;
00048 }
00049 
00050 /**
00051  * Version récursive du calcul du pgcd
00052  */
00053 int pgcd_rec(int a, int b) {
00054     int e = (a < 0)?-a:a;
00055     int f = (b < 0)?-b:b;
00056     if (f == 0) return e;
00057     return pgcd_rec(f, e%f);
00058 }
00059 
00060 /**
00061  * Calcul des coefficients de Bezout tels que d = pgcd(a,b) = a.u + b.v
00062  * @return   d = pgcd(a,b)
00063  */
00064 int bezout(int a, int b, int * u, int * v) {
00065     int e = (a < 0)?-a:a;
00066     int f = (b < 0)?-b:b;
00067     *u = 1;
00068     *v = 0;
00069     int u_aux = 0, v_aux = 1;
00070     int q, r, tmp;
00071     while (f > 0) {
00072         q = e/f;
00073         r = e%f;
00074         e = f;
00075         f = r; 
00076         tmp = u_aux; u_aux = *u - q*u_aux; *u = tmp;
00077         tmp = v_aux; v_aux = *v - q*v_aux; *v = tmp;
00078     }
00079     if (a < 0) *u = -(*u);
00080     if (b < 0) *v = -(*v);
00081     return e;
00082 }
00083 /**
00084  * Calcul de l'inverse de a modulo n.
00085  * @return   0 en cas de succès, 1 en cas d'echec (si pgcd(a,n)=1)
00086  */
00087 int inv_mod(int a, int n, int * res) {
00088     int d, u, v;
00089     d = bezout(a, n, &u, &v);
00090     if (d == 1) {
00091         *res = (n + u) % n;
00092         return 0;
00093     }
00094     return 1;
00095 }