III. Factorisation d'un nombre entier
(un exemple de programme)
function vfp=FactoriseEntier(n)
% factoriseEntier - détermine la décomposition en facteurs premiers d'un entier
% USAGE: vfp=factoriseEntier(n)
% n : nombre scalaire entier positif, le nombre entier à factoriser.
% n négatif ou non entier déclenche une erreur.
% n supérieur à 2^53==flintmax (le plus grand entier vraiment codable en 'double float') déclenche également une erreur.
% ATTENTION: des arguments de l'ordre de 2^53-1=~9E15 conduisent à des calculs longs (de l'ordre de
% ~quelques secondes) et requièrent de grande quantité de mémoire vive. Il est préférable
% que n ne dépasse pas ~1E14 pour limiter les temps de calcul et la mémoire requise.
% vfp: vecteur d'entiers, les facteurs premiers de n, en ordre ascendant.
% (Il sera par convention retourné un vecteur vide pour n valant 0 ou 1)
if ~isnumeric(n) || ~isreal(n) || ~isscalar(n) || mod(n,1)~=0 || n<0 || n>2^53
error('L''argument n n''est pas un nombre scalaire entier positif plus petit que 2^53')
% Arrêt de la fonction avec message d'erreur dans la Command Window en cas de violation des spécifications sur n
end
% Ici, n est nécessairement correct puisque la fonction ne s'est pas arrêtée sur un appel de error dans le if ci-dessus...
m=floor(sqrt(n));
vp=primes(m); % les nombres premiers <= sqrt(n).
% ATTENTION: le calcul ci-dessus peut être lourd si n est grand (>~1E14).
% NOTA: primes(0) et primes(1) retournent un vecteur vide.
nt=n; % n ‘de travail’ (on conservera le n originel inchangé)
vfp=zeros(1,0); % initialisation de vfp comme vecteur (ligne) vide.
for p=vp % pour tous les nombres premiers <= sqrt(n)
while mod(nt,p)==0 % tant que nt est divisible par p (p est le nbr premier <= sqrt(n) "courant")
vfp=[vfp p];
nt=nt/p;
end
if nt==1;break;end % évite de tester les nombres premiers plus grands si la décomposition est déjà finie!
end
if nt>1 % cas de l'existence de l'unique facteur premier >sqrt(n) dans la factorisation de n
vfp=[vfp nt]; % on concatène ce dernier facteur premier au vecteur des autres facteurs
end
ASSERT((n<2 && isempty(vfp)) || (n>=2 && prod(vfp)==n))
% on affirme(vérifie) que le produit des termes trouvés vaut bien n (ou que vfp est vide pour n=0 ou 1)
>> FactoriseEntier(2) % test simple
ans =
2
>> FactoriseEntier(16) % test simple
ans =
2 2 2 2
>> FactoriseEntier(9) % test simple
ans =
3 3
>> FactoriseEntier(40) % cas général simple
ans =
2 2 2 5
>> FactoriseEntier(200) % cas général simple
ans =
2 2 2 5 5
>> FactoriseEntier(9999) % cas général
ans =
3 3 11 101
>> FactoriseEntier(103) % nombre premier
ans =
103
>> FactoriseEntier(2*103) % nbr composite avec un facteur > sqrt(n)
Il peut souvent y avoir des erreurs de programmation sur ce cas
ans =
2 103
>> FactoriseEntier(2^19-1) % (nombre de Mersenne)
ans =
524287
>> FactoriseEntier(2^23-1) % (nombre de Mersenne)
ans =
47 178481
>> FactoriseEntier(2^53-1) % (nombre de Mersenne)
~
Plus grand nombre entier codable en “double float” (
⇒
plusieurs secondes de calcul!)
ans =
6361 69431 20394401
>> FactoriseEntier(1) % cas particulier
ans =
Empty matrix: 1-by-0
>> FactoriseEntier(0) % cas particulier
ans =
Empty matrix: 1-by-0
>> FactoriseEntier(1.2) % cas interdit (nombre non entier)
Error using FactoriseEntier (line 14)
L'argument n n'est pas un nombre scalaire entier positif plus petit que 2^53
>> FactoriseEntier([99 999 9999]) % cas interdit (vecteur)
Error using FactoriseEntier (line 14)
L'argument n n'est pas un nombre scalaire entier positif plus petit que 2^53
>> FactoriseEntier(-999) % cas interdit (nombre négatif)
Error using FactoriseEntier (line 14)
L'argument n n'est pas un nombre scalaire entier positif plus petit que 2^53
>> FactoriseEntier(2E16) % cas interdit
(nombre entier trop grand pour être correctement manipulé en “double”)
Error using FactoriseEntier (line 14)
L'argument n n'est pas un nombre scalaire entier positif plus petit que 2^53