JAVA - Produit factoriel

Résolu/Fermé
totodunet Messages postés 1377 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 5 mars 2020 - 9 oct. 2012 à 20:54
cloridee Messages postés 47 Date d'inscription lundi 16 janvier 2012 Statut Membre Dernière intervention 9 juin 2023 - 27 nov. 2012 à 18:08
Bonjour, on me demande de réaliser un programme en JAVA avec jGRASP.

Le principe est simple : l'utilisateur entre un nombre n et le programme lui sort le produit factoriel de ce nombre. Il faut que le résultat soit obtenu par boucle conditionnelle (while).

J'ai alors écrit ceci :

import java.util.Scanner;
public class Factorielle
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Entrez un nombre n :");
int n = sc.nextInt();
int a=n-1;
int r;
if (n<=0)
{
r=1;
}
else
{
while(a!=0)
{
a=a-1;
r=n*a;
}
}
System.out.print("Le produit factoriel de "+n+" est : "+r);
}
}

J'ai un problème au moment de la compilation :(
Il me dit que r n'est pas défini :?

Si vous arrivez à me dire la bêtise que j'ai omise...

Merci infiniment pour votre aide!


A voir également:

3 réponses

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
Modifié par KX le 9/10/2012 à 21:28
Dans ton code il y a bien un problème avec r (entre autre) mais il ne s'agit pas d'un problème de déclaration mais d'initialisation. Parce que si n==1, tu auras a==0, donc ton if te conduit directement au else, mais qui n'exécutera jamais la boucle while. En conséquence r n'aura pas de valeur, et ne peux pas être affiché... Il faut donc lui donner une première valeur !La confiance n'exclut pas le contrôle
0
totodunet Messages postés 1377 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 5 mars 2020 199
9 oct. 2012 à 22:25
ah oui merci ! j'avais pas vu ça moi...

j'ai tout refait et il y avait aussi un problème d'une part tu as raison de l'initialisation et aussi dans la boucle;
voici la solution :

import java.util.Scanner;
public class Factorielle
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Entrez un nombre n :");
int n = sc.nextInt();
int a=n-1;
int r=n*a;
if (n<=0)
{
r=1;
}
else
{
while(a>1)
{
a=a-1;
r=r*a;
}
}
System.out.print("Le produit factoriel de "+n+" est : "+r);
}
}

Merci bcp!!
0
totodunet Messages postés 1377 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 5 mars 2020 199
9 oct. 2012 à 22:52
j'ai parlé trop vite, à partir de n=13, le programme me donne un résultat vraiment étrange !

j'ai passé ça au débogueur et c'est plus que bizarre ce qu'il se passe... à un moment il trouve un r négatif ???
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
9 oct. 2012 à 23:05
Les nombres entiers sont limités en Java (et dans les autres langages)
Un int est codé sur 32 bits, si on enlève le bit de signe, ça signifie que les valeurs possibles vont de -2^31 à 2^31-1, soit -2 147 483 648 à +2 147 483 647

Or 13! dépasse cette valeur puisqu'il vaut 6 227 020 800, et comme le résultat déborde il passe en négatif avant finalement d'obtenir 1 932 053 504 qui correspond bien à la bonne valeur mais à 2^32 près.

13! = 6 227 020 800 = 2^32 + 1 932 053 504

C'est pour ça que l'on a d'autres types de données que les int, par exemple les long codés sur 64 bits, qui permettent d'atteindre des valeurs plus grandes (n=20 maximum)
0
totodunet Messages postés 1377 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 5 mars 2020 199
10 oct. 2012 à 18:56
ah d'accord merci ! ça dépend donc de la type de variable. et il y a-t-il un type de variable qui permet encore d'atteindre beaucoup plus grand que long ? par exemple il pourrait me calculer 99! sous forme d'écriture scientifique bien sûr même si c'est ridicule
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
10 oct. 2012 à 19:39
Pour les écritures scientifiques tu as les float et les double mais tu n'auras pas la valeur exacte et ils seront eux aussi limités à un moment donné, environ 2^128 c'est à dire 34! pour les float, et 2^1024 c'est à dire 170! pour les double.

Pour obtenir de très grandes valeurs exactes, tu peux utiliser la classe BigInteger, là il n'y a alors plus aucune limite si ce n'est la mémoire de la JVM. 99! est alors très facile à faire...

Remarque 1 : Pour atteindre de très très grandes valeurs exactes (100000! par exemple) il faut repenser l'algorithme parce qu'il y a des contraintes supplémentaires qui viennent s'ajouter : les types primitifs avaient une taille fixe donc le temps nécessaire pour faire une multiplication était constant, or avec les BigInteger le temps de la multiplication va dépendre de la taille des entiers que l'on multiplie. L'ordre dans lequel on multiplie les entiers va donc être crucial. Multiplier à chaque fois (n-1)! et n, est une mauvaise idée car (n-1)! est beaucoup plus grand que n, il vaut mieux multiplier toujours deux nombres de tailles proches, par exemple(n/2)! et n!/(n/2)!

Remarque 2 : En utilisant les logarithmes, on peut obtenir très rapidement des valeurs approchées de très grands nombres factoriels. On ne calcule alors plus le produit des entiers pour obtenir la factorielle, mais la somme des log10 de ces entiers pour obtenir le log10 de la factorielle. C'est un résultat généralement suffisant, l'intérêt d'avoir la valeur exacte étant minime.

D'un point de vue algorithmique, les factorielles sont très intéressantes...
0
down5221 Messages postés 14 Date d'inscription mardi 9 octobre 2012 Statut Membre Dernière intervention 10 octobre 2012 6
Modifié par down5221 le 9/10/2012 à 23:01
Il te suffit juste d'appeler 'r'

int r = 0;

car
r=r*a; le R est vide a par si c'est dans le If mais si le Else est le cas alors le R est vide!
0
down5221 Messages postés 14 Date d'inscription mardi 9 octobre 2012 Statut Membre Dernière intervention 10 octobre 2012 6
9 oct. 2012 à 23:04
0
totodunet Messages postés 1377 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 5 mars 2020 199
10 oct. 2012 à 18:51
je te remercie ! j'ai procédé un peu différemment dans les variables mais il y a aussi cette solution
0
cloridee Messages postés 47 Date d'inscription lundi 16 janvier 2012 Statut Membre Dernière intervention 9 juin 2023 8
27 nov. 2012 à 10:59
Salut,
il faut initialisé le r à 0 car le r est contenu dans des blocs de conditions et il ne sais pas la valeur à la base que aura le r quand les blocs commencerons.

donc int r =0;

JE PENSE, dis moi si c'est ça bien sûr.
0
BenassK Messages postés 1 Date d'inscription mardi 27 novembre 2012 Statut Membre Dernière intervention 27 novembre 2012
27 nov. 2012 à 11:33
J'aurais initialisé r à 1 car si tu mets r=0, r=n*a sera toujours égal a 0 donc c'est comme si tu n'avais rien fait alors que si tu mets 1, la valeur obtenue de n*a sera multipliée par 1 donc ne changera pas et a la fin tu aboutiras au vrai résultat
0
cloridee Messages postés 47 Date d'inscription lundi 16 janvier 2012 Statut Membre Dernière intervention 9 juin 2023 8
27 nov. 2012 à 18:08
Exact merci :) !
0