Conversion : BigInteger en 3.14 exp 300 ?

Résolu
Bonsoir à tous,
je cherche à afficher un nombre dépassant le type long au format
exponentiel exemple :
   public BigInteger bigFactorielle(int j) {
     try {
       BigInteger result = BigInteger.valueOf(1);
       for(int i=2; i < j; i++) {
         result = result.multiply(BigInteger.valueOf(i));
       }
       return result;
    }catch(Exception e) {}
    return BigInteger.valueOf(0);


factorielle de 40 = 2. 04 puissance 46.
merci pour vos infos
A+

--
le réel n'est jamais ce que l'on croit, mais ce qu'on n'aurait dû penser.[...]

5 réponses

  • Votes
  • Date
  • Date décroissante
  1. Contributeur
    Slt,

    Il va falloir envisager de se plonger un peu plus loin dans le calcul que tu veux faire...
    Il va falloir que tu implémentes une classe "BigNumber" qui réalise ton calcul de manière fractionnée et qui puisse les contenir de manière adéquate (voir java.math.BigInteger), surtout si tu as besoin d'un minimum de précision.

    Qui plus est je te conseille de penser à mettre des garde-fou sur les valeurs que tu prends car tu risques de partir dans des calculs rapidement très longs!

    Good luck
    1. Salut emmanuelP,
      merci de ta réponse, en fait je ne me sert des BigInteger que parceque je m'amuse à faire une petite appli qui permet de calculer
      les combinaisons et les permutations possibles d'un groupe d'éléments, pour répondre à une autre questions qui à été posée sur le forum. je n'ai pas vraiment utilité de manipuler le format d'un bigInteger sinon à titre indicative pour le faire tenir par exemple dans un JOptionPane qui ne fait pas la largeur de la pièce... sa veritable valeur n'est pas modifiée.
      ce n'est pas du calcul savant, d'ailleurs je te demande si tu est familier des grands nombres : est-ce possible d'imprimer dans un fichier autant de lignes qu'il y a de permutations possibles dans un ensemble quand ce chiffre dépasse le type long, c'est peut-être un peu tiré par les cheveux non ?
      Au niveau des garde-fou c'est clair qui faudra pas cherché à calculer la factorielle de la distance de la terre au soleil, mais je pense que 'int j' en paramètre limite un peu, quoique, tu as raison, je viens de tester factorielle de 10 000 et il faut déjà quelque seconde pour afficher : 2.846 10^35655, alors je vais y songer...oups:/j'avais failli tester avec un million mais ouf.
      Pour l'heure je me suis dépatouiller en implementant ceci :
      	/********************************************
      	 * Permet de mettre un nombre au format puissance de 10 selon une precision passée en paramètre.
      	 * @param result le nombre sous forme de chaîne,
      	 * @param precision le précision voulue, nombre de chiffre aprés la virgule,
      	 * @return la chaîne représentant le nombre result sous une forme '0,n precision 10 ^ x'.
      	 */
        public String getFormatP10(String result, int precision) {
          if("".equals(result) || result == null) return "Erreur resultat";
         //	liste des chiffres
        final List tmp = 
          Arrays.asList(new String ("0,1,2,3,4,5,6,7,8,9").split(","));	
        String res = result.charAt(0) + ",";//premier chiffre + virgule
        int compt = 1;                       //	un compteur d'unité
        int taille = result.length();//	taille totale du résultat
        while(compt < taille && compt < precision) {	
        //  tant que parcour non fini et precision non atteinte 
        res += result.charAt(compt++); 
        }
        if(compt >= taille) {	                         //  si le nombre est trop petit
          while(--precision > 0) res += "0";//  remplace les chiffres abs
          res += " 10^" + (compt - 1);	   //  par 0, elève à la puissance
          return res;		   //  retourne 
        }
        //	indice dans la liste
         int ind1 = tmp.indexOf(result.charAt(compt) + "");
        //  indice du chiffre suivant
        int ind2 = tmp.indexOf(result.charAt(compt + 1) + "");
        if (ind2 >= 5) ind1 += 1;	  //   arrondi à sup si suivant >= 5
        //    mise en forme du résultat
        res += ind1 + " 10^" + (taille + precision - (compt + 1));
        return res;
      }/* ************************************************ fin 
      

      a voir ...
      ciao A+.
      1. Contributeur
        Slt,

        J'ai jeté un rapide coup d'oeil à ton code et je pense que tu peux mettre à profit qques unes des fonctions de la classe String:

        public String  getFormatP10(String result, int precision){
        
                //on prend en compte la presence eventuelle d une virgule
                int indexVirgule=result.indexOf(",");
                
                //longueur de la chaine
                int longueur=result.length();
        
                //init de la puissance de 10
                int puissance=0;
        
                if (indexVirgule>0){
                    //si la virgule est dans la chaine
                    puissance=indexVirgule-1; 
                } 
                else if (longueur>0){ 
                    //sinon si la chaine a au moins 1 element
                    puissance=longueur-1;
                }else {   
                    //chaine vide (on peut aussi lever une exception)
                    return "0";                
                }
        
        
               //on place le premier elt dans la chaine resultat
               String res=result.charAt(0);
        
                //si la precision est >0 on a besoin de la virgule
                if (precision>0) res+=",";
        
                if (longueur<=precision) {
                    //la precision demandee est > au nombre de decimales
                    res+=result.substring(1, longueur);
        
                    for (int i=longueur;i<=precision;i++){
                        //on rajoute des 0 de bourrage pour conserver le format
                        res+="0";
                    }
                }
                else {
                    //sinon on prend les decimales dont on a besoin
                    res+=result.substring(1, precision+1);
                }
               
                //on rajoute l indication de puissance
                res+=" 10^"+puissance;
                return res;
            }


        Pour ce qui est de ta seconde question, le type long est codé sur 64 bits donc si tu envisages d'imprimer 2^64 lignes (environ 1,8.10^19) ça risque d'être longuet à relire!

        Good luck

        PS: je n'ai pas fait tourner le code=> a verifier et corriger ...
      2. @emmanuelPBonsoir emmanuelP
        super je regarde çà en détail illico merci ...
        à toute ...
      3. @emmanuelPoui biens sûr, plus simple plus concis...
        note que je ne prenais en compte ici que les entiers et les BigInteger, donc pas soucis de virqule mais aprés tout, comme je manipule une chaîne représentant un nombre, autant adapter pour d'autre cas de figures, je modifierai bientôt, d'ailleurs j'ai presque fini : c'est pour afficher les permutations d'un ensemble d'éléments : 2^63 permutations à imprimer, je me demande si c'est vraiment utile humhum...
    2. Salut!

      Pourquoi vous cassez la tête alors que vous pouvez travailler avec des double à la place des long?

      /*
       * Created on 06-déc.-2005
       * Author: HackTrack
       */
      
      public class DemoFactorielle {
      
      	public DemoFactorielle() {
      		super();
      	}
      
      	public double fact(double n) {
      		if (n == 0)
      			return 0;
      		if (n == 1)
      			return 1;
      		return (n * fact(n - 1));
      	}
      
      	public static void main(String[] args) {
      		DemoFactorielle tester = new DemoFactorielle();
      		int x = 40;
      		System.out.println("La factorielle de " + x +" est "+ tester.fact((double)x));
      	}
      }
      


      ;-)
      HackTrack
      1. Salut HackTrack,
        merci, vouis ben à la base c'est çà que je cherchais, ce format :
        8.159152832478977E47
        peux-tu me dire si c'est sous cette forme parceque c'est un double ?
        peux t-on reproduire cette forme pour n'importe quel chiffre ?
        c'est cà que je voulais savoir .... car le blême c'est qu'avec des doubles DemoFactorielle renvoie Infinity pour x = 1000, alors que BigFactorielle à de la marge; ainsi : comment faire que ma factorielle de 1000 :
        402387260077093773543702433923003985719374864
        2107146325437999104299385123986290205920442084869694048004799886101971960586316668729948085589013238296699445909974245040870737599188236277271887325197795059509952761208749754624970436014182780946464962910563938874378864873371191810458257836478499770124766328898359557354325131853239584630755574091142624174743493475534286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713483120254785893207671691324484262361314125087802080002616831510273418279777047846358681701643650241536913982812648102130927612448963599287051149649754199093422215668325720808213331861168115536158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021394503997362807501378376153071277619268490343526252000158885351473316117021039681759215109077880193931781141945452572238655414610628921879602238389714760885062768629671466746975629112340824392081601537808898939645182632436716167621791689097799119037540312746222899880051954444142820121873617459926429565817466283029555702990243241531816172104658320367869061172601587835207515162842255402651704833042261439742869330616908979684825901254583271682264580665267699586526822728070757813918581788896522081643483448259932660433676601769996128318607883861502794659551311565520360939881806121385586003014356945272242063446317974605946825731037900840244324384656572450144028218852524709351906209290231364932734975655139587205596542287497740114133469627154228458623773875382304838656889764619273838149001407673104466402598994902222217659043399018860185665264850617997023561938970178600408118897299183110211712298459016419210688843871218556461249607987229085192968193723886426148396573822911231250241866493531439701374285319266498753372189406942814341185201580141233448280150513996942901534830776445690990731524332782882698646027898643211390835062170950025973898635542771967428222487575867657523442202075736356949882508796892816275384886339690995982628095612145099487170124451646126037902930912088908694202851064018215439945715680594187274899809425474217358240106367740459574178516082923013535808184009699637252423056085590370062427124341690900415369010593398383577793941097002775347200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
        mettons, soit imprimable sous cette forme :
        x.xxxxxxxxxxEY
        je me demande si possible ...
        A+
        1. Contributeur
          Slt,

          Note qu'on s'en fout un peu (beaucoup) de savoir si on travaille avec des long, doubles, reals,... vu que de toute façon on les a sous forme de String... l'interessant dans ce cas est de rendre correctement la puissance...
          La "cerise sur le gateau" c'est 5 lignes pour gérer la virgule correctement...
          on rentre une chaine pour faire un affichage autant pas s'em***der à faire des conversions inutiles!

          Good luck