Problema algoritmo lento...

di il
31 risposte

31 Risposte - Pagina 2

  • Re: Problema algoritmo lento...

    Korr ha scritto:


    Grazie per le ulteriori indicazioni.

    Sto gia' facendo alcune letture ed esperimenti.

    Vedro' cosa si puo' fare.
    Se ti può interessare ho preparato uno stub di quella che potrebbe essere un'implementazione del pool:

    MyAllocator.h:
    
    #include <stdlib.h>
    
    void *Malloc(size_t size);
    void *Realloc(void *ptr, size_t size);
    void Free(void *ptr);
    
    MyAllocator.c:
    
    #include "MyAllocator.h"
    #include "List.h"
    #define POOL_SIZE 10
    #define MIN_POOL_BLOCK_SIZE 4 // minimum size is 2^4
    
    struct item {
    	void *start;
    	void *end;
    };
    
    typedef List * Pool;
    
    Pool free_blocks, allocated_blocks;
    
    void *Malloc(size_t size) {
    	void *ptr;
    	Item i;
    	int power_of_two=0, discrete_size=1;
    	static int pool_exists; // Automatically initialized to 0, mantain its status in the subsiquent calls
    	if(!pool_exists) {
    		if(PCreate())
    			pool_exists=1;
    		else {
    			perror("Memory pool allocation error");
    			exit(-1);
    		}
    	}
    	
    	do
    		power_of_two++;
    	while((size/=2)>=2);
    	power_of_two++;
    	discrete_size<<=power_of_two; // Much more efficient than pow
    	
    	if(!(i=GetFirstBlock(free_blocks, power_of_two))) {
    		if(!(ptr=malloc(discrete_size+sizeof(int))))
    			return NULL;
    		i=ICreate();
    		SetItemPtr(i, ptr);
    	}
    	AddBlock(allocated_blocks, power_of_two, i);
    	
    	return ptr;
    }
    
    void *Realloc(void *ptr, size_t size) {
    	;
    }
    
    void Free(void *ptr) {
    	Item i=RemoveBlock(allocated_blocks, SetItemPtr(ICreate(), ptr));
    	int power_of_two=GetItemPowerOfTwo(i);
    	AddBlock(free_blocks, power_of_two, i);
    }
    
    List.h:
    
    typedef struct list *List;
    typedef struct item *Item; //To be implemented by the user
    
    List LCreate();
    int Push(List, Item);
    Item Pop(List);
    Item Find(List, Item);
    Item Remove(List, Item);
    int Size(List);
    
    Item ICreate(); //To be implemented by the user
    int ICompare(Item, Item); //To be implemented by the user
    
    Quello che devi fare è implementare la lista (o usare un'implementazione già pronta che svolga le stesse funzioni) in un file List.c, implementare Item e relative funzioni in MyAllocator.c e implementare le varie funzioni GetFirstBlock, AddBlock ecc., sempre in MyAllocator. Infine devi implementare Realloc.

    P.S.: non ho verificato che il codice funzioni, anche perché, ovviamente, non avendo definito alcune funzioni il codice non compila.
  • Re: Problema algoritmo lento...

    Sto cercando di portare questo codice :
     
     
     #include<stdio.h>
     #include<stdlib.h>
     
        int main ()
    
    {
    
    	long long int a = 0;
    
    	long long int b = 0;
    
    	long long int c = 0;
    
    	long long int d = 0;
    
    	long long int e = 0;
    
    	long long int f = 0;
    
    printf("Trovare i due fattori di un prodotto\n\n");
    
           
    	printf("Inserire numero N dispari (prodotto) : \n");
    	scanf(&a);
        printf("Inserire numero N1 dispari minore di N (divisore) : ");
    	scanf(&b);
    
    	while ( a != (e) )
    
    	{
    
    		d = a / b;
    
    		e = b*d;
    		b = b-2;
    
    		if (e == a)
    
    		{
    			printf(d,"Fattore Primo 1: ");
    
    			f = a / d;
    
    			printf(f,"\n\nFattore Primo 2: ");
    
    		
    		
    		]}
    all'interno del programma di Korr ma in pratica ho messo sul file supernum_lib.h , questo :
          void factor(supernum *a , supernum *b , supernum *c , supernum *d , supernum *e );
    
    mentre su supernum_lib.c questo :
     void factor( supernum *a , supernum *b , supernum *c , * supernum *d , supernum *e )
    
    { 
    
    unsigned int ciclo , lungh , lungh2;
    char divisione , moltiplic;
    
    lungh=b->n_cifre;
    
    
    
    while ( lungh != moltiplic)
    
    {
    
    moltiplic = (divisione * b->v_cifre[ciclo]);
    
    
    
    lungh2 = b->v_cifre[ciclo] - 2;
    
    c->v_cifre[ciclo]=lungh2;
    
    e->v_cifre[ciclo] = moltiplic;
    
    for(ciclo = 0; ciclo < lungh ; ciclo++)
    
    {
    
    divisione = a->v_cifre[ciclo]/b->v_cifre[ciclo];
    d->v_cifre[ciclo]=divisione;
    }
    }    
    e su operaz.c
       if (opz ==888)
    {
    printf("\n%s","Dividendo:  ");
             leggi_sup(&a);
             printf("\n%s","Divisore:  ");
             leggi_sup(&b);
    printf("\n%s","Fattore Primo :   ");
    mostra_sup(&b);
    }
    
    quindi gentilmente mi potete spiegare dove sbaglio ?
  • Re: Problema algoritmo lento...

    Hai errori?
  • Re: Problema algoritmo lento...

    oregon ha scritto:


    Hai errori?
    C:\Users\aleas\Desktop>gcc operaz.c supernum_lib.h
    operaz.c:12:1: warning: return type defaults to 'int' [-Wimplicit-int]
     main()
     ^
    supernum_lib.h:43:34: error: unknown type name 'FILE'
     void aaa(unsigned char *stringa, FILE *ff, char a_capo);
                                      ^
    
  • Re: Problema algoritmo lento...

    In supernum_lib.h manca una include di stdio.h e il main deve essere int main() e alla fine ci vuole un return 0
  • Re: Problema algoritmo lento...

    oregon ha scritto:


    In supernum_lib.h manca una include di stdio.h e il main deve essere int main() e alla fine ci vuole un return 0
    Fatto ma adesso mi da questo :
         C:\Users\aleas\Desktop>gcc operaz.c supernum_lib.h
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x2a): undefined reference to `azzera_supernum'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x39): undefined reference to `azzera_supernum'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x48): undefined reference to `azzera_supernum'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x57): undefined reference to `azzera_supernum'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x66): undefined reference to `azzera_supernum'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x75): more undefined references to `azzera_supernum' follow
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0xcd): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0xf0): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x115): undefined reference to `somma_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x138): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x169): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x18c): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x1b1): undefined reference to `sottraz_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x1fb): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x22c): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x24f): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x274): undefined reference to `moltip_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x297): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x2f1): undefined reference to `divis_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x300): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x31a): undefined reference to `confronta_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x386): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x3a9): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x3ef): undefined reference to `divis_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x439): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x45c): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x495): undefined reference to `moltip_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x4ba): undefined reference to `somma_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x4c9): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x4e3): undefined reference to `confronta_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x54f): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x572): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x5aa): undefined reference to `potenza_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x5cf): undefined reference to `potenza_sup_2'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x61a): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x66a): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x697): undefined reference to `fattor_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x6e2): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x72e): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x751): undefined reference to `leggi_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x774): undefined reference to `mostra_sup'
    C:\Users\aleas\AppData\Local\Temp\ccqQkJII.o:operaz.c:(.text+0x854): undefined reference to `leggi_stringa'
    collect2.exe: error: ld returned 1 exit status
  • Re: Problema algoritmo lento...

    Questi sono ALTRI errori.

    Probabilmente nel file operaz.c non c'è un include in cui dichiari tutte quelle funzioni (moltip_sup, mostra_sup, divis_sup ....)
  • Re: Problema algoritmo lento...

    Nel file dove c'è il main devi includere anche i tuoi header, e poi quando compili devi passare a gcc solo i file .c
  • Re: Problema algoritmo lento...

    Si ho messo .h invece di .c comunque mi da questi errori adesso :
      C:\Users\aleas\Desktop>gcc operaz.c supernum_lib.c
    supernum_lib.c:933:6: error: conflicting types for 'divis_sup'
     char divis_sup(supernum *a,supernum *b,supernum *c,supernum *d)
          ^
    In file included from supernum_lib.c:8:0:
    C:/Users/aleas/Desktop/supernum_lib.h:39:6: note: previous declaration of 'divis_sup' was here
     char divis_sup(supernum *a, supernum *b, supernum *c, supernum *d ,supernum *e , supernum *f);
          ^
    supernum_lib.c: In function 'casuale_sup':
    supernum_lib.c:985:9: warning: implicit declaration of function 'time' [-Wimplicit-function-declaration]
       srand(time(NULL));
             ^
    supernum_lib.c: In function 'leggi_sup_file':
    supernum_lib.c:1075:12: warning: implicit declaration of function 'isdigit' [-Wimplicit-function-declaration]
            if (isdigit(carattere))
                ^
    Poi vi metto supernum_lib.h :
        /*                 SUPERNUM_LIB.H                 */
    /* Autore: Corrado Damiano                        */
    /* Data ultima versione: 28-12-2016               */
    
    // numero di cifre di un supernumero
    # define DIMENS 100000
    #include <stdio.h>   
    typedef struct
     {
      unsigned int n_cifre;
      char v_cifre[DIMENS];
     } supernum;
    
    void factor(supernum *a , supernum *b , supernum *c , supernum *d , supernum *e , supernum *f);
    
    void leggi_stringa(char *stringa, int lunghezza);
    void azzera_supernum(supernum *a);
    void assegna_sup(supernum *a, supernum *b);
    char char_byte(char n);
    char byte_char(char n);
    void leggi_sup(supernum *a);
    void mostra_sup(supernum *a);
    char zero_sup(supernum *a);
    char uno_sup(supernum *a);
    char confronta_sup(supernum *a, supernum *b);
    void somma_sup(supernum *a, supernum *b, supernum *c);
    
    char sottraz_sup(supernum *a, supernum *b, supernum *c);
    void increm_sup(supernum *a);
    void increm_sup_2(supernum *a, supernum *b);
    void moltip_cifra(char cifra, supernum *a, supernum *b);
    char trasla_sup(unsigned int t, supernum *a);
    char moltip_sup(supernum *a, supernum *b, supernum *c);
    char moltip_sup_2(supernum *a, supernum *b, supernum *c);
    char fattor_sup(supernum *a, supernum *b);
    char potenza_sup(supernum *a, supernum *b, supernum *c);
    char potenza_sup_2(supernum *a, supernum *b, supernum *c);
    char trova_multiplo(supernum *a, supernum *b, supernum *m, supernum *n);
    char divis_sup(supernum *a, supernum *b, supernum *c, supernum *d ,supernum *e , supernum *f);
    void casuale_sup(supernum *a, unsigned int lungh_max);
    void salva_sup_file(supernum *a, char *nome_file);
    char leggi_sup_file(supernum *a, char *nome_file);
    void aaa(unsigned char *stringa, FILE *ff, char a_capo);
    void salva_sup_html(supernum *a, char *nome_file);
    
    /* ---------------------- FINE SUPERNUM_LIB.H ---------------------- */
    
    // www.corradodamiano.it a cura di Corrado Damiano
    
    
    
    
    poi supernum_lib.c completo dove alla fine c'è il mio codice :
       /*                   SUPERNUM_LIB.C                   */
    /* Autore: Corrado Damiano                            */
    /* Data ultima versione: 28-1-2016                    */
    
    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    # include "C:/Users/aleas/Desktop/supernum_lib.h"
    
    /* ----------------------------------------------- */
    
        // legge una stringa
        // la variabile lunghezza e' pari al numero massimo di caratteri 
        // che possono essere inseriti nella stringa, piu' un byte che 
        // deve contenere il valore 0 (terminatore di stringa); 
        // se viene inserito un numero di caratteri superiore a quello 
        // previsto (lunghezza-1), i caratteri in eccesso vengono ignorati, 
        // pero' rimangono nel buffer della tastiera
    void leggi_stringa(char *stringa, int lunghezza)
     {
      char carattere;
      int indice;
        // assegna 0 a tutti gli elementi della stringa
      for (indice=0; indice<lunghezza; indice++)  
          {stringa[indice]=0;}
        // legge i singoli caratteri con getchar()
        // il ciclo si interrompe quando si digita invio 
        // (che inserisce il terminatore di stringa) 
        // o quando si e' raggiunto il numero massimo 
        // di caratteri inseribili
      indice=0;
      while (((carattere=getchar())!='\n')&&(indice<lunghezza-1))
       {
        stringa[indice++]=carattere;
       }
     }    // fine leggi_stringa()
    
    /* --------------------------------------------------------- */
    
        // inizializza un supernumero
        // assegnandogli il valore 0
    void azzera_supernum(supernum *a)
     {
      unsigned int ciclo;
    
      // il numero 0 e' formato da 1 cifra
      a->n_cifre=1;
      for (ciclo=0; ciclo<DIMENS; ciclo++)  
          {a->v_cifre[ciclo]=0;}
     }   // fine azzera_supernum
    
    /* ---------------------------------------------------------- */
    
        // assegna il supernumero a al supernumero b
    void assegna_sup(supernum *a,supernum *b)
     {
      unsigned int ciclo, lungh;
    
      lungh=a->n_cifre;
      azzera_supernum(b);
      for (ciclo=0; ciclo<lungh; ciclo++)
          {b->v_cifre[ciclo]=a->v_cifre[ciclo];}
      b->n_cifre=lungh;
     }   // fine assegna_sup()
    
    /* ------------------------------------------------------------- */
    
        // dato in input un carattere che rappresenta una cifra, 
        // rende in uscita il byte corrispondente
    char char_byte(char n)
     {
      if (n=='0') return 0;
      if (n=='1') return 1;
      if (n=='2') return 2;
      if (n=='3') return 3;
      if (n=='4') return 4;
      if (n=='5') return 5;
      if (n=='6') return 6;
      if (n=='7') return 7;
      if (n=='8') return 8;
      if (n=='9') return 9;
     }   // fine char_byte()
    
    /* --------------------------------------------------------- */
    
        // l'inversa della precedente
    char byte_char(char n)
     {
      if (n==0) return '0';
      if (n==1) return '1';
      if (n==2) return '2';
      if (n==3) return '3';
      if (n==4) return '4';
      if (n==5) return '5';
      if (n==6) return '6';
      if (n==7) return '7';
      if (n==8) return '8';
      if (n==9) return '9';
     }   // fine byte_char()
    
    /* -------------------------------------------------------- */
    
        // legge un supernumero
    void leggi_sup(supernum *a)
     {
      char stringa[DIMENS];
      char cifra;
      int ciclo, conta, lungh, k;
    
      leggi_stringa(stringa, (DIMENS+1));
    
        // conta i caratteri inseriti in stringa
      conta=0;
      do
        {
         cifra=stringa[conta];
         conta++;
        } while (cifra!=0);
      lungh=conta-1;
    
        // inserisce - al contrario - i caratteri di stringa 
        // in v_cifre[]
      k=0;
      for (ciclo=(lungh-1); (ciclo>=0); ciclo--) 
        {
         a->v_cifre[k]=stringa[ciclo];
         k++;
        } 
    
        // trasforma in byte i caratteri inseriti; serve per i calcoli
      for (ciclo=0; ciclo<lungh; ciclo++)
        {
         a->v_cifre[ciclo]=char_byte(a->v_cifre[ciclo]);
        }  
    
        // assegna il valore del numero di cifre 
      a->n_cifre=lungh;
     }   // fine leggi_sup()
    
    /* ------------------------------------------------------------ */
    
        // mostra un supernumero, facendolo precedere (fra parentesi) 
        // dalla sua lunghezza
    void mostra_sup(supernum *a)
     {
      int ciclo, lungh;
      lungh=a->n_cifre;
    
        // mostra il numero di cifre del supernumero
      printf("%s%d%s", "(",lungh, ")  ");
    
        // mostra, leggendo v_cifre[] al contrario, le varie cifre
      for (ciclo=(lungh-1); ciclo>=0; ciclo--)
        {printf("%c", byte_char(a->v_cifre[ciclo]));} 
     }   // fine mostra_sup()
    
    /* --------------------------------------------------------------- */
    
        // se un supernumero e' pari a 0 rende in uscita 1, 
        // altrimenti rende 0
    char zero_sup(supernum *a)
     {
      if ((a->n_cifre==1)&&(a->v_cifre[0]==0)) return 1;
         {return 0;}
     }
    
    /* ---------------------------------------------------------------- */
     
        // se un supernumero e' pari a 1 rende in uscita 1, 
        // altrimenti rende 0
    char uno_sup(supernum *a)
     {
      if ((a->n_cifre==1)&&(a->v_cifre[0]==1)) return 1;
      return 0;
     }   // fine uno_sup()
    
    /* ----------------------------------------------------------------- */
    
        // confronta due supernumeri a e b; rende in uscita 0 se sono uguali, 
        // 1 se e' maggiore il primo, 2 se e' maggiore il secondo
    char confronta_sup(supernum *a, supernum *b)
     {
      long ciclo,lungh;
    
      if (a->n_cifre > b->n_cifre) return 1;
      if (b->n_cifre > a->n_cifre) return 2;
        // i due supernumeri hanno la stessa quantita' di cifre
        // confronta tutte le cifre a partire dall'ultima di v_cifre[]
      lungh=a->n_cifre;
      for (ciclo=(lungh-1); ciclo>=0; ciclo--)
          {
           if (a->v_cifre[ciclo] > b->v_cifre[ciclo]) return 1;
           if (b->v_cifre[ciclo] > a->v_cifre[ciclo]) return 2;
          }
      return 0;
     }   // confronta_sup()
    
    /* ------------------------------------------------------------- */
    
        // somma i supernumeri a e b, e assegna il risultato a c
    void somma_sup(supernum *a, supernum *b, supernum *c)
     {
      unsigned int ciclo, lungh;
      char somma, riporto;
    
      if (a->n_cifre >= b->n_cifre) 
         {lungh=a->n_cifre;}
      else 
         {lungh=b->n_cifre;}
    
      riporto=0;
      for (ciclo=0; ciclo<lungh; ciclo++)
          {
           somma=a->v_cifre[ciclo]+b->v_cifre[ciclo]+riporto;
           if (somma>9)
              {
               somma-=10;
               riporto=1;
              }
           else
             {riporto=0;}
           c->v_cifre[ciclo]=somma;
          }
    
      if (riporto==1)
         {
          c->n_cifre=lungh+1;
          c->v_cifre[ciclo]=1;
         }
      else
         {c->n_cifre=lungh;}
     }   // fine somma_sup()
    
    /* -------------------------------------------------------------- */
    
        // sottrae b ad a e assegna il risultato a c
    char sottraz_sup(supernum *a,supernum *b,supernum *c)
     {
      unsigned int ciclo, lungh_a, n_zeri;
      char prestito, k, cfr;
      cfr=confronta_sup(a, b);
      if (cfr==2) 
         {return 1;}
    
      n_zeri=0;
      prestito=0;
      lungh_a=a->n_cifre;
      for (ciclo=0; ciclo<lungh_a; ciclo++)
          {
           k=a->v_cifre[ciclo]-prestito;
           if (b->v_cifre[ciclo] > k)
              {
               k=k+10;
               k=k-b->v_cifre[ciclo];
               prestito=1;
              }
           else
              {
               k=k-b->v_cifre[ciclo];
               prestito=0;
              }
           c->v_cifre[ciclo]=k;  
           if (k==0) {n_zeri++;}
           else {n_zeri=0;}
          }   // fine ciclo for
    
        // misura la lunghezza del risultato, considerando il caso
        // in cui il valore del numero e' zero e la sua lunghezza e' 1
      if (lungh_a==n_zeri) 
         {c->n_cifre=1;}
      else  
         {c->n_cifre=a->n_cifre-n_zeri;}
      return 0;
     }   // fine sottraz_sup()
    
    /* --------------------------------------------------------- */
    
        // incrementa di una unita' un supernumero
        // serve per le variabili contatore di ciclo
    void increm_sup(supernum *a)
     {
      supernum s1;
      supernum s2;
    
      azzera_supernum(&s1);
      azzera_supernum(&s2);
      s1.n_cifre=1;
      s1.v_cifre[0]=1;
      assegna_sup(a, &s2);
      somma_sup(&s1, &s2, a);
     }   // fine increm_sup()
    
    /* ------------------------------------------------------------ */
    
        // incrementa il valore di a sommando il valore di b
    void increm_sup_2(supernum *a, supernum *b)
     {
      supernum n1;
    
      assegna_sup(a, &n1);
      somma_sup(&n1, b, a);
     }   // fine increm_sup_2()
    
    /* ----------------------------------------------------------- */
    
        // moltiplica per cifra il supernumero a 
        // e il risultato viene assegnato a b
        // serve per la moltiplicazione di due supernumeri
        // e anche per la divisione
    void moltip_cifra(char cifra, supernum *a,supernum *b)
     {
      unsigned int ciclo, lungh;
      unsigned int prodotto, riporto, decine, unita;
    
        // preparazione variabili per il ciclo for
      riporto=0;
      lungh=a->n_cifre;
    
        // esegue il prodotto di tutte le cifre del supernumero a
      for (ciclo=0; ciclo<(lungh); ciclo++)
          {
           prodotto=(cifra*a->v_cifre[ciclo])+riporto;
           unita=prodotto % 10;
           decine=prodotto / 10;
           riporto=0;
           if (decine!=0)
              {riporto=decine;}
           b->v_cifre[ciclo]=unita;
          }   // fine ciclo for
    
      if (riporto==0)
         {b->n_cifre=lungh;}
      else
         {
          b->n_cifre=lungh+1;
          b->v_cifre[ciclo]=riporto;
         }
     }    // fine moltip_cifra()
    
    /* -------------------------------------------------------------- */
    
        // trasla le cifre di un supernumero, nella misura indicata con t;
        // agli spazi lasciati liberi assegna il valore 0
        // serve per la moltiplicazione e la divisione fra due supernumeri
    char trasla_sup(unsigned int t, supernum *a)
     {
      unsigned int ciclo, lungh, inizio, fine;
    
      if (t==0) 
         {return 0;}
      lungh=a->n_cifre;
      inizio=lungh+t-1;
      fine=inizio-lungh+1;
        // trasla le cifre in base al valore di t
      for (ciclo=inizio; ciclo>=fine; ciclo--)
          {
           a->v_cifre[ciclo]=a->v_cifre[ciclo-t];
          }
        // assegna 0 agli spazi liberati
      for (ciclo=0; ciclo<t; ciclo++)
          {
           a->v_cifre[ciclo]=0;
          }
    
        // aggiorna la lunghezza del supernumero
      a->n_cifre=lungh+t;
      return 0;
     }   // fine trasla_sup()
    
    /* -------------------------------------------------------------- */
    
        // moltiplica a per b e assegna il risultato a c
    char moltip_sup(supernum *a, supernum *b, supernum *c)
     {
      unsigned int ciclo, lungh_a, lungh_b, traslaz;
      supernum s1, s2, s3;
    
      azzera_supernum(&s1);
      azzera_supernum(&s2);
      azzera_supernum(&s3);
      azzera_supernum(c);
      lungh_a=a->n_cifre;
      lungh_b=b->n_cifre;
    
        // bisogna prevedere il caso particolare in cui almeno uno 
        // dei fattori abbia valore 0
      if (zero_sup(a)||zero_sup(b))    
         {
          c->n_cifre=1;
          return 0;
         }
    
        // moltiplica i due supernumeri
      for (ciclo=0; ciclo<lungh_a; ciclo++)
          {
           moltip_cifra(a->v_cifre[ciclo], b, &s1);
           trasla_sup(ciclo, &s1);
           somma_sup(&s1, &s2, &s3);
           assegna_sup(&s3, &s2);
           azzera_supernum(&s1);      
           azzera_supernum(&s3);
          }   // fine ciclo for
    
      assegna_sup(&s2, c);
     }   // fine moltip_sup()
    
    /* ---------------------------------------------------------- */
    
        // moltiplica a per b e assegna il risultato a c;
        // riduce il numero delle moltiplicazioni, rispetto a moltip_sup(), 
        // pero' e' un po' piu' lenta; sto indagando sul motivo
    char moltip_sup_2(supernum *a, supernum *b, supernum *c)
     {
      unsigned int ciclo;
      supernum *v_multipli[10];
      supernum n1, n2;
      supernum *aa, *bb;
      char cifra;
      
        // bisogna prevedere il caso particolare in cui almeno uno 
        // dei fattori abbia valore 0
      if (zero_sup(a)||zero_sup(b))
         {
          azzera_supernum(c);
          return 0;
         }
    
      azzera_supernum(&n1); 
      azzera_supernum(&n2);
    
        // alloca spazio in mmeoria per i supernumeri 
        // puntati da aa, bb
      aa=calloc(1, sizeof(supernum));
      bb=calloc(1, sizeof(supernum));
    
      if (a->n_cifre < b->n_cifre) 
         {
          assegna_sup(a, bb);
          assegna_sup(b, aa);
         }
      else
         {
          assegna_sup(a, aa);
          assegna_sup(b, bb);
         }
    
        // assegna NULL a tutti gli elementi di v_multipli[]
        // questo vettore puntera' a tutti i prodotti effettuati 
        // fra ognuna delle cifre presenti nel moltiplicatore 
        // e il moltiplicando
      for (ciclo=0; ciclo<10; ciclo++)
          {v_multipli[ciclo]=NULL;}
    
        // legge tutte le cifre del moltiplicatore 
        // e le moltiplica per il moltiplicando, inserendo il risultato 
        // in v_multipli; evita di ripetere piu' di una volta lo stesso prodotto
      for(ciclo=0; ciclo < bb->n_cifre; ciclo++)  
         {
          cifra=bb->v_cifre[ciclo];    
          if (v_multipli[cifra]==NULL)
             {
              if (cifra==0)
                 {
                  v_multipli[cifra]=calloc(1, sizeof(supernum));
                  assegna_sup(&n1, v_multipli[cifra]);
                 }   
              else
                 { 
                  moltip_cifra(cifra, aa, &n1);    
                  v_multipli[cifra]=calloc(1, sizeof(supernum));
                  assegna_sup(&n1, v_multipli[cifra]);
                 }
              azzera_supernum(&n1);
             }
         } 
    
        // legge tutte le cifre del moltiplicatore
        // per ogni cifra, legge il prodotto corrispondente in v_multipli[]
        // poi il prodotto viene traslato in base alla posizione della cifra 
        // (indicata da ciclo) e il risultato viene aggiunto alla variabile n2, 
        // che svolge la funzione di accumulatore
      for (ciclo=0; ciclo < bb->n_cifre; ciclo++)   
          {
           cifra=bb->v_cifre[ciclo];    
           assegna_sup(v_multipli[cifra], &n1);      
           if (cifra!=0) 
              {trasla_sup(ciclo, &n1);}
           increm_sup_2(&n2, &n1);
           azzera_supernum(&n1);
          }  
    
        // dealloca la memoria
      for (ciclo=0; ciclo<10; ciclo++)
          {
           if (v_multipli[ciclo]!=NULL)
              {
               free(v_multipli[ciclo]);
               v_multipli[ciclo]=NULL;
              }
          }
    
      assegna_sup(&n2, c);
     }   // fine moltip_sup_2()
    
    /* -------------------------------------------------------------- */
    
        // calcola il fattoriale di a e assegna il risultato a b
    char fattor_sup(supernum *a, supernum *b)
     {
      supernum ciclo,n1,n2;
      char cfr;
    
      if (zero_sup(a))
         {
          b->n_cifre=1;
          b->v_cifre[0]=1;
          return 0;
         }
    
      if (uno_sup(a))
         {
          b->n_cifre=1;
          b->v_cifre[0]=1;
          return 0;
         }
    
      azzera_supernum(&ciclo);
      azzera_supernum(&n1);
      azzera_supernum(&n2);
      ciclo.n_cifre=1;
      ciclo.v_cifre[0]=1;
      n1.n_cifre=1;
      n1.v_cifre[0]=1;
      do
        {
         moltip_sup(&ciclo, &n1, &n2);
         assegna_sup(&n2, &n1);
         increm_sup(&ciclo);
         cfr=confronta_sup(a, &ciclo);
        } while(cfr!=2);
    
      assegna_sup(&n1, b);
      return 0;
     }   // fine fattor_sup()
    
    /* ----------------------------------------------------------------- */
    
        // calcola la potenza di un supernumero: a e' la base, 
        // b e' l'esponente, c e' il risultato
        // usa l'algoritmo veloce
        // il valore char in uscita indica se la potenza e' calcolabile (0) o no (1)
        // ho lasciato sotto commento alcune istruzioni utili per verificare 
        // il comportamento della funzione
    char potenza_sup(supernum *a, supernum *b, supernum *c)
     {
        // struct che rappresenta una singola potenza della base a
      struct scheda 
       {
        supernum esponente;
        supernum potenza;
        char utile;
        struct scheda *p_scheda;
       };
    
        // variabili per gestire la successione di potenze
      struct scheda v_potenze[20];
      struct scheda sch;
      struct scheda *p_radice, *p_temp;
      unsigned int indice, j, n_potenze;
    
        // variabili per i cicli
      char continua_1, continua_2, ciclo;
    
        // variabili per i calcoli
      supernum k, doppio_k, residuo;
      supernum *n1, *n2, *n3;
      char cfr;
    
        // variabile per contare le moltiplicazioni
      unsigned int conta;
    
        // gestione casi particolari
        // l'esponente e' uguale a 0
      if (zero_sup(b))
         {
          // anche la base e' uguale a 0
          if (zero_sup(a))
             {
              return 1;
             }
          // la base e' diversa da 0
          c->n_cifre=1;
          c->v_cifre[0]=1;
          return 0;
         }
    
        // la base e' uguale a 1
      if (uno_sup(a))
         {
          assegna_sup(a, c);
          return 0;
         }
    
        // alloca spazio in memoria heap per le variabili dinamiche
      n1=calloc(1, sizeof(supernum));
      n2=calloc(1, sizeof(supernum));
      n3=calloc(1, sizeof(supernum));
    
        // inizializza le variabili locali/dinamiche
      azzera_supernum(n1);
      azzera_supernum(n2);
      azzera_supernum(n3);
      azzera_supernum(&k);
      azzera_supernum(&doppio_k);
      azzera_supernum(&residuo);
    
        // riempie v_potenze[]
        // nel primo elemento viene messa la potenza con esponente 1
      //printf("\n\n%s\n","Creazione tabella esponenti/potenze...");
      conta=0;
      sch.esponente.n_cifre=1;
      sch.esponente.v_cifre[0]=1;
      assegna_sup(a,&sch.potenza);
      sch.utile=0;
      sch.p_scheda=NULL;
      v_potenze[0]=sch;
      n_potenze=1;
        // gli altri elementi si ottengono moltiplicando - ad ogni ciclo - 
        // la potenza precedente per se' stessa; si ottiene cosi' una successione 
        // di potenze il cui esponente e' sempre pari al doppio dell'esponente 
        // precedente; gli esponenti ottenuti sono tutti potenze di 2; 
        // il ciclo si ferma quando ha raggiunto il massimo esponente inferiore 
        // o uguale a quello passato in input
      indice=1;
      k.n_cifre=1;
      k.v_cifre[0]=1;
      continua_1=1;
      do
        {
         moltip_cifra(2, &k, &doppio_k);
         cfr=confronta_sup(&doppio_k, b);
         if ((cfr==0)||(cfr==2))
            {
             assegna_sup(&v_potenze[indice-1].potenza,n1);
             moltip_sup(n1, n1, n2); 
             conta++;
             //printf("\n%d\n",conta);
             azzera_supernum(&doppio_k);
             moltip_cifra(2, &k, &doppio_k);
             assegna_sup(&doppio_k, &sch.esponente);  
             assegna_sup(&doppio_k, &k);
             assegna_sup(n2, &sch.potenza);
             sch.utile=0;
             sch.p_scheda=NULL;
             v_potenze[indice]=sch;
             indice++;
             n_potenze++;
            }
         else {continua_1=0;}
         azzera_supernum(&doppio_k);
        } while(continua_1==1);
    
        // inverte l'ordine degli elementi di v_potenze[]
        // usando una pila; 
        // copia gli elementi di v_potenze[] nella pila
      //printf("\n%s\n","Inserimento schede esponenti/potenze nella pila...");
      p_radice=NULL;
      p_temp=NULL;
      p_radice=calloc(1, sizeof(struct scheda));
      (*p_radice)=v_potenze[0];
      for (ciclo=1; ciclo<n_potenze; ciclo++)
          {
           p_temp=calloc(1, sizeof(struct scheda));
           (*p_temp)=v_potenze[ciclo];
           p_temp->p_scheda=p_radice;
           p_radice=p_temp;
           p_temp=NULL;
          }
    
        // copia gli elementi dalla pila a v_potenze[]
    //printf("\n%s\n","Dalla pila alla tabella, in ordine inverso...");
      for (ciclo=0; ciclo<n_potenze; ciclo++)
          {
           v_potenze[ciclo]=(*p_radice);
           v_potenze[ciclo].p_scheda=NULL;
           p_temp=p_radice->p_scheda;
           free(p_radice);
           p_radice=p_temp;
           p_temp=NULL;
          }
      p_radice=NULL;
    
        // individua gli esponenti utili, cioe' quelli che sommati fra loro 
        // danno un valore pari all'esponente passato in input;
        // al campo utile di questi esponenti viene assegnato il valore 1
        // il primo esponente di v_potenze[] rientra sempre fra gli esponenti utili
    //printf("\n%s\n","Ricerca esponenti utili...");
      v_potenze[0].utile=1;
      sottraz_sup(b, &v_potenze[0].esponente, &residuo);
    
        // prosegue nella ricerca degli esponenti utili 
        // solo se il residuo e' diverso da 0
      if (!((residuo.n_cifre==1)&&(residuo.v_cifre==0)))
         {
          // il ciclo esterno cerca tutti gli esponenti utili 
          // assegnando 1 al campo utile
          j=0;
          indice=j+1;
          continua_1=1;
          do
            {
             // il ciclo interno cerca il singolo esponente utile
             // dopo l'aggiornamento del residuo
             continua_2=1;
             do
               {
                cfr=confronta_sup(&v_potenze[indice].esponente, &residuo);
                if ((cfr==0)||(cfr==2))
                   {
                    v_potenze[indice].utile=1;
                    j++;
                    continua_2=0;
                   }
                else
                   {
                    indice++;
                    if (indice==n_potenze) continua_2=0;
                   }
               } while(continua_2==1);   // fine ciclo do-while interno
    
             assegna_sup(&residuo, &k);
             sottraz_sup(&k, &v_potenze[indice].esponente, &residuo);
             if ((residuo.n_cifre==1)&&(residuo.v_cifre[0]==0)) 
                {continua_1=0;}
            } while(continua_1==1);   // fine ciclo do-while esterno
         }   // fine if per il caso primo residuo !=0
    
        // calcola la potenza
      //printf("\n%s\n\n","Calcolo potenza...");
      conta=0;
      assegna_sup(&v_potenze[0].potenza, n1);
      for (ciclo=1; ciclo<n_potenze; ciclo++)
          {
           if (v_potenze[ciclo].utile==1)
              {
               assegna_sup(&v_potenze[ciclo].potenza, n2);
               //  moltip_sup(n1,&v_potenze[ciclo].potenza,n2);
               moltip_sup(n1, n2, n3);
               conta++;
               // printf("\n%d\n",conta);
               // assegna_sup(n2,n1);
               assegna_sup(n3, n1);
              }
          }   // fine ciclo for per il calcolo della potenza
      
      assegna_sup(n1, c);
      free(n1);
      free(n2);
      free(n3);
      return 0;  
     }   // fine potenza_sup()
    
    /* --------------------------------------------------------------- */
    
        // calcola la potenza di un supernumero: a e' la base,  
        // b e' l'esponente, c e' il risultato
        // usa l'algoritmo 'ingenuo'
    char potenza_sup_2(supernum *a, supernum *b, supernum *c)
     {
      unsigned int ciclo;  
      supernum s1, s2, superciclo;
      azzera_supernum(&s1);
      azzera_supernum(&s2);
    
        // gestione casi particolari
        // l'esponente e' uguale a 0
      if (zero_sup(b))
         {
          // anche la base e' uguale a 0
          if (zero_sup(a))
             {return 1;}
          // la base e' diversa da 0
          c->n_cifre=1;
          c->v_cifre[0]=1;
          return 0;
         }
    
        // la base e' uguale a 1
      if (uno_sup(a))
         {
          assegna_sup(a, c);
          return 0;
         }
    
      azzera_supernum(&superciclo);
      superciclo.n_cifre=1;
      superciclo.v_cifre[0]=1;
      assegna_sup(a, &s1);
    
      while (confronta_sup(&superciclo,b)==2)
          {
           moltip_sup(a, &s1, &s2);
           assegna_sup(&s2, &s1);
           azzera_supernum(&s2);
           increm_sup(&superciclo);
          }
    
      assegna_sup(&s1, c);
      return 0; 
     }   // fine potenza_sup_2()
    
    /* ------------------------------------------------------------- */
    
        // trova un opportuno multiplo di b sottraibile ad a; 
        // il valore di questo multiplo viene assegnato a m; 
        // a n viene assegnato il numero di volte in cui b e' contenuto in m
        // se il multiplo viene trovato, rende in uscita 1, altrimenti rende 0;
        // questa funzione serve per la divisione fra supernumeri
    char trova_multiplo(supernum *a,supernum *b,supernum *m,supernum *n)
     {
      unsigned int n_zeri;
      char confronto, continua, k;
      supernum z, t, sup_preced, n_preced;
    
      azzera_supernum(m);
      azzera_supernum(n);
      confronto=confronta_sup(a, b);
    
        // se b>a, esce dalla funzione rendendo in uscita 0
      if (confronto==2) return 0;
    
        // se a=b, b viene assegnato a m, 1 viene assegnato a n 
        // e rende in uscita 1 
      if (confronto==0)
         {
          assegna_sup(b, m);
          n->v_cifre[0]=1;
          n->n_cifre=1;
          return 1;
         } 
    
        // a>b e i due numeri hanno lo stesso numero di cifre
      if (a->n_cifre == b->n_cifre)
         {
          assegna_sup(b,&sup_preced);
          for (k=2; k<=9; k++)
              {
               moltip_cifra(k, b, &z);
               confronto=confronta_sup(a, &z);
               if (confronto==0)
                  {
                   assegna_sup(&z, m);
                   n->v_cifre[0]=k;
                   n->n_cifre=1;               
                   return 1;
                  }
               if (confronto==2)
                  {
                   assegna_sup(&sup_preced,m);
                   n->v_cifre[0]=k-1;
                   n->n_cifre=1;
                   return 1;
                  }
               assegna_sup(&z, &sup_preced);
              }  // fine ciclo for
    
          // se arriva fin qui, significa che il nono multiplo di b e' inferiore ad a
          assegna_sup(&z, m);
          n->v_cifre[0]=9;
          n->n_cifre=1;
          return 1;
         }  // fine if (a>b e i due numeri hanno lo stesso numero di cifre
    
        // a ha un numero di cifre superiore a b
        // calcola la differenza fra il numero delle cifre dei due numeri
      n_zeri=a->n_cifre-b->n_cifre;
    
      pizza:
      assegna_sup(b, &t);
      trasla_sup(n_zeri, &t);
      confronto=confronta_sup(a, &t);
    
      if (confronto==0)
         {
          assegna_sup(&t, m);
          n->v_cifre[0]=1;
          n->n_cifre=1;
          trasla_sup(n_zeri,n);
          return 1;
         }
    
      if (confronto==2) 
         {
          n_zeri--;
          goto pizza;
         }
    
      for (k=2; k<=9; k++)
          {
           moltip_cifra(k, &t, &z);
           confronto=confronta_sup(a, &z);
           if (confronto==0)
              {
               assegna_sup(&z, m);
               n->v_cifre[0]=k;
               n->n_cifre=1;
               trasla_sup(n_zeri, n);
               return 1;
              }       
           if (confronto==2)
              {
               moltip_cifra((k-1), &t, &z);
               assegna_sup(&z, m);
               n->v_cifre[0]=k-1;
               n->n_cifre=1;
               trasla_sup(n_zeri, n);
               return 1;
              }
          }  // fine ciclo for
      assegna_sup(&z, m);
      n->v_cifre[0]=9;
      n->n_cifre=1;
      trasla_sup(n_zeri, n);
      return 1;
     }   // fine trova_multiplo()
    
    /* ---------------------------------------------------------------- */
    
        // divide a per b, il quoziente lo mette in c e il resto in d
        // l'algoritmo funziona mediante una sequenza di sottrazioni 
        // (al dividendo/residuo) di opportuni multipli del divisore
        // calcolati con trova_multiplo()
    char divis_sup(supernum *a,supernum *b,supernum *c,supernum *d)
     {
      char continua, confronto;
      supernum m1, m2, m3, n1, n2, n3, r1, r2, r3;
    
      if ((b->v_cifre[0]==0)&&(b->n_cifre==1)) 
         {return 1;}
    
      azzera_supernum(&m1);
      azzera_supernum(&m2);
      azzera_supernum(&m3);
      azzera_supernum(&n1);
      azzera_supernum(&n2);
      azzera_supernum(&n3);
      azzera_supernum(&r1);
      azzera_supernum(&r2);
      azzera_supernum(&r3);
    
      assegna_sup(a, &r1);
      continua=1;
      do 
        {
         trova_multiplo(&r1, b, &m1, &n1);
         increm_sup_2(&m2, &m1);
         increm_sup_2(&n2, &n1);
         sottraz_sup(&r1, &m1, &r2);
         confronto=confronta_sup(&r2, b);
         if (confronto==2) 
            {continua=0;}
         else 
            {
             assegna_sup(&r2, &r1);
             azzera_supernum(&r2);
            }
        } while (continua==1);
    
      assegna_sup(&n2, c);
      assegna_sup(&r2, d);
      return 0;
     }  // fine divis_sup()
    
    /* -------------------------------------------------------------- */
    
        // crea un supernumero casuale
    void casuale_sup(supernum *a, unsigned int lungh_max)
     {
      unsigned int ciclo, lungh_sup;
      char n_char;
    
      azzera_supernum(a);
    
        // inizializza il generatore di numeri casuali
      srand(time(NULL));
    
        // determina la lunghezza del supernumero, 
        // in modo che sia diversa da 0
      do 
        {
         lungh_sup=(rand() % (lungh_max+1));
        } while (lungh_sup==0);
    
      a->n_cifre=lungh_sup;
    
        // la lunghezza del supernumero e' uguale a 1
      if (lungh_sup==1)
         {
          a->v_cifre[0]=rand() % 10;
         }
        // la lunghezza del supernumero e' diversa da 1
      else
         {
          // determina casualmente tutte le cifre del supernumero, 
          // tranne l'ultima (corrispondente alla pot. di 10 piu' alta)
          for (ciclo=0; ciclo<(lungh_sup-1); ciclo++)
              {
               a->v_cifre[ciclo]=rand() % 10;
              }
    
          // determina casualmente l'ultima cifra, in modo che sia diversa da 0       
          do 
            {
             n_char=rand() % 10;
            } while (n_char==0);
          a->v_cifre[lungh_sup-1]=n_char;
         }  // fine else lunghezza diversa da 1
    
     }   // fine casuale_sup()
    
    /* --------------------------------------------------------------- */
    
        // salva in un file le cifre di un supernumero
        // le cifre sono rappresentate da caratteri
    //void salva_sup_file(supernum *a, char *nome_file)
     //{
     // char carattere;
     // int ciclo,k,conta;
    //  FILE *f_cifre;
    
    //  f_cifre=fopen(nome_file, "ab");
    //  k=a->n_cifre;
    
     // conta=1;
     // for (ciclo=(k-1); ciclo>=0; ciclo--)
       //   {
        //   carattere=byte_char(a->v_cifre[ciclo]);
        //   fwrite(&carattere, 1, 1, f_cifre);
         //  if ((conta % 100)==0)
         //     {
          //     carattere=10;   // a capo
           //    fwrite(&carattere, 1, 1, f_cifre);
             // }
          // conta++;
       //   }   // fine ciclo for
    
    //  fclose(f_cifre);
     // }    // fine salva_sup_file()
    
    /* --------------------------------------------------------------- */
    
        // legge le cifre di un file di caratteri e le colloca 
        // in un supernumero
    char leggi_sup_file(supernum *a, char *nome_file)
     {
      char carattere;
      int ciclo, k, conta;
      unsigned int num_cifre, dim_file;
      FILE *f_cifre;
    
      f_cifre=fopen(nome_file, "rb");
      if (f_cifre==NULL) 
         {return 1;}
    
      num_cifre=0;
      fseek(f_cifre, 0, SEEK_END);
      dim_file=ftell(f_cifre);
      fseek(f_cifre, 0, SEEK_SET);
    
        // legge tutti i byte del file, 
        // contando le cifre carattere
      for (ciclo=1; ciclo<=dim_file; ciclo++)
          {
           fread(&carattere, 1, 1, f_cifre);       
           if (isdigit(carattere)) 
              {num_cifre++;}
          }
    
        // percorre una seconda volta il file, inserendo nel supernumero 
        // tutte le cifre lette, convertite in byte
      k=num_cifre-1;
      fseek(f_cifre, 0, SEEK_SET);
      for (ciclo=1; ciclo<=dim_file; ciclo++)
          {
           fread(&carattere, 1, 1, f_cifre);
           if (isdigit(carattere))
              {
               a->v_cifre[k]=char_byte(carattere);
               k--;
              }
          }
    
      a->n_cifre=num_cifre;
      fclose(f_cifre);
      return 0;
     }    // fine leggi_sup_file()
    
    /* --------------------------------------------------------------- */
    
        // scrive una stringa (tag o altro) in un file HTML 
        // a_capo indica se aggiungere il terminatore di riga byte 10
    void aaa(unsigned char *stringa, FILE *ff, char a_capo)
     {
      unsigned int lungh_str, k;
      unsigned char carattere;
    
      lungh_str=strlen(stringa);
      for (k=0; k<lungh_str; k++)
          {
           carattere=stringa[k];
           fwrite(&carattere, 1, 1, ff);
          }
      
      if (a_capo==1)
         {
          carattere=10;
          fwrite(&carattere, 1, 1, ff);
         }
     }   // fine aaa()
    
    /* --------------------------------------------------------------- */
    
        // salva in un file HTLM le cifre che compongono un supernumero
    void salva_sup_html(supernum *a, char *nome_file)
     {
      char carattere;
      int ciclo, k, conta;
      FILE *f_cifre;
    
      f_cifre=fopen(nome_file, "ab");
      k=a->n_cifre;
    
      aaa("<HTML>", f_cifre, 1);
      aaa("<BODY  BGCOLOR=\"#D3D3D3\">", f_cifre, 1);
    
      conta=1;
      for (ciclo=(k-1); ciclo>=0; ciclo--)
          {
           carattere=byte_char(a->v_cifre[ciclo]);
           fwrite(&carattere, 1, 1, f_cifre);
           if ((conta % 100)==0)
              {aaa("<BR>", f_cifre, 1);}
           conta++;
          }   // fine ciclo for
    
      carattere=10;
      fwrite(&carattere, 1, 1, f_cifre);
      aaa("</BODY>", f_cifre, 1);
      aaa("</HTML>", f_cifre, 1);
    
      fclose(f_cifre);
     }    // fine salva_sup_html()
    
    
    
    void factor( supernum *a , supernum *b , supernum *c , supernum *d , supernum *e , supernum *f)
    
    { 
    
    int ciclo , lungh , lungh2;
    char divisione , moltiplic;
    
    lungh=b->n_cifre;
    
    
    
    while ( lungh != moltiplic)
    
    {
    
    
    for(ciclo = 0; ciclo < lungh ; ciclo++)
    
    {
    
    divisione = a->v_cifre[ciclo]/b->v_cifre[ciclo];
    d->v_cifre[ciclo]=divisione;
    }
    
    
    
    moltiplic = (divisione * b->v_cifre[ciclo]);
    
    
    
    lungh = b->v_cifre[ciclo] - 2;
    
    c->v_cifre[ciclo]=lungh2;
    
    e->v_cifre[ciclo] = moltiplic;
    
    }
    
    }
    
    /* ----------------------- FINE SUPERNUM_LIB.C ------------------------ */
    
    // www.corradodamiano.it a cura di Corrado Damiano
    
    
    
    
    
    
    
    e operaz.c completo dove alla fine c'è il mo codice :
        /*                  OPERAZ.C                 */
    /* Autore: Corrado Damiano                   */
    /* Data ultima versione: 28-1-2016           */
    
    # include <stdio.h>
    # include <stdlib.h>
    # include <time.h>
    # include "C:/Users/aleas/Desktop/supernum_lib.h"
    
    char scelta();
    
    int main()
     {
      char opz,continua,confronto,errore,tasto;
      supernum a,b,c,d,e,f,quoz,resto;
      time_t inizio,fine;
      unsigned int secondi;  
    
      continua=1;
      do
        {
         azzera_supernum(&a);    
         azzera_supernum(&b);
         azzera_supernum(&c);    
         azzera_supernum(&d);
         azzera_supernum(&e);
         azzera_supernum(&f);
         azzera_supernum(&quoz); 
         azzera_supernum(&resto);
         opz=scelta();
         if (opz==1)    // somma
            {
             printf("\n%s","Primo numero:  ");
             leggi_sup(&a);
             printf("\n%s","Secondo numero:  ");
             leggi_sup(&b);
             somma_sup(&a,&b,&c);
             printf("\n%s","La somma e' ");
             mostra_sup(&c);
            }
         if (opz==2)    // sottrazione
            {
             printf("\n%s","Minuendo:  ");
             leggi_sup(&a);
             printf("\n%s","Sottraendo:  ");
             leggi_sup(&b);
             errore=sottraz_sup(&a,&b,&c);
             if (errore==1) 
                {
                 printf("\n%s","Non calcolabile...");
                }
             else 
                {
                 printf("\n%s","La differenza e' ");
                 mostra_sup(&c);
                }
            }
        if (opz==3)    // prodotto
            {
             printf("\n%s","Moltiplicando:  ");
             leggi_sup(&a);
             printf("\n%s","Moltiplicatore:  ");
             leggi_sup(&b);
             moltip_sup(&a,&b,&c);
            //  moltip_sup_2(&a,&b,&c);
            printf("\n%s","Il prodotto e' ");
             mostra_sup(&c);
             printf("\n\n%s\n","Prova (prodotto / moltiplicatore = moltiplicando)");
             divis_sup(&a,&b,&c,&d,&e,&f);
             mostra_sup(&quoz);
             confronto=confronta_sup(&a,&quoz);
             if (confronto==0) printf("\n%s","Giusto");
             else printf("\n%s","Sbagliato");
            }
         if (opz==4)    // divisione
            {
             printf("\n%s","Dividendo:  ");
             leggi_sup(&a);
             printf("\n%s","Divisore:  ");
             leggi_sup(&b);
            errore=divis_sup(&a,&b,&c,&d, &e,&f);
             if (errore==1) 
                {
                 printf("\n%s\n","Non calcolabile...");
                }
             else
                {
                 printf("\n%s","Il quoziente e' ");
                 mostra_sup(&c);
                 printf("\n%s","Il resto e' ");
                 mostra_sup(&d);
                }
             printf("\n\n%s\n","Prova (quoziente * divisore + resto = dividendo)");
             moltip_sup(&c,&b,&e);
             somma_sup(&e,&d,&f);
             mostra_sup(&f);
             confronto=confronta_sup(&a,&f);
             if (confronto==0) printf("\n%s","Giusto");
             else printf("\n%s","Sbagliato");
            }
         if (opz==5)    // potenza
            {
             printf("\n%s","Base:  ");
             leggi_sup(&a);
             printf("\n%s","Esponente:  ");
             leggi_sup(&b);
             inizio=time(0);
             potenza_sup(&a,&b,&c);
             potenza_sup_2(&a,&b,&c);
             fine=time(0);
             secondi=fine-inizio;
             printf("\n%s","La potenza e' ");
             mostra_sup(&c);
             printf("\n\n%s%d","Secondi:  ",secondi);
            }
         if (opz==6)    // fattoriale
            {
             printf("\n%s","Numero:  ");
             leggi_sup(&a);
             inizio=time(0);
             fattor_sup(&a,&b);
             fine=time(0);
             secondi=fine-inizio;
             printf("\n%s","Il fattoriale e' ");
             mostra_sup(&b);
             printf("\n\n%s%d","Secondi:  ",secondi);
            }
         
    if (opz ==8)
    {
    printf("\n%s","Dividendo:  ");
             leggi_sup(&a);
             printf("\n%s","Divisore:  ");
             leggi_sup(&b);
    printf("\n%s","Fattore Primo :   ");
    mostra_sup(&b);
    }
    
    if (opz==7) {
    
    continua=0; 
    
    }  // fine
        } while(continua==1);
    
      printf("\n\n");
      return 0;
     }
    
    /* ----------------------------------------------------------- */
    
        // mostra un menu per la scelta dell'operazione 
        // da effettuare sui supernumeri
    char scelta()
     {
      char opzione;
      char opzione_str[2];
      printf("\n%s\n","---------------------------------------------");
      printf("%s\n","OPERAZIONI CON SUPERNUMERI");
      printf("%s\n","Somma....................1");
      printf("%s\n","Sottrazione..............2");
      printf("%s\n","Prodotto.................3");
      printf("%s\n","Divisione................4");
      printf("%s\n","Potenza..................5");
      printf("%s\n","Fattoriale...............6");
      printf("%s\n","Uscita dal programma.....7");
      printf("%s\n","Fattorizzzz..............8");
    
    
      printf("\n%s","Scegliere operazione:  ");
      leggi_stringa(opzione_str, 2);
      opzione=atoi(opzione_str);
      return opzione;
     }  // fine scelta()
    
    /* ------------------------ FINE OPERAZ.C -------------------------- */
    
    // www.corradodamiano.it a cura di Corrado Damiano
    
    
    
    
    
  • Re: Problema algoritmo lento...

    Leggi gli errori e gli avvisi.

    Per la funzione divis_sup, come vedi, ne trova due diverse

    char divis_sup(supernum *a,supernum *b,supernum *c,supernum *d)

    char divis_sup(supernum *a, supernum *b, supernum *c, supernum *d ,supernum *e , supernum *f);

    e quindi devi decidere quale è quella giusta.

    Per le funzioni time e isdigit mancano gli include necessari (vedi la documentazione di tali funzioni).
  • Re: Problema algoritmo lento...

    oregon ha scritto:


    Leggi gli errori e gli avvisi.

    Per la funzione divis_sup, come vedi, ne trova due diverse

    char divis_sup(supernum *a,supernum *b,supernum *c,supernum *d)

    char divis_sup(supernum *a, supernum *b, supernum *c, supernum *d ,supernum *e , supernum *f);

    e quindi devi decidere quale è quella giusta.

    Per le funzioni time e isdigit mancano gli include necessari (vedi la documentazione di tali funzioni).
    Si funziona adesso , Thanks. (dovevo levare anche dei "\\" su su supernum_lib.c)

    --EDIT--


    ma c'è qualcosa che non funziona sulle operazioni ......
  • Re: Problema algoritmo lento...

    Sulle operazioni (ovvero sull'algoritmo usato e sul codice utilizzato) è tutta un'altra storia.
  • Re: Problema algoritmo lento...

    oregon ha scritto:


    Sulle operazioni (ovvero sull'algoritmo usato e sul codice utilizzato) è tutta un'altra storia.
    Infatti...purtroppo non capisco i passaggi , in pratica devo assegnare un numero con
    numero->n_cifre;
    Poi per dividerlo devo metterlo su un ciclo for ...e per sottrarre ogni volta -2 , devo ripetere il ciclo...

    Sbaglio?
  • Re: Problema algoritmo lento...

    Purtroppo e sottolineo purtroppo a me serve il programma che funzioni al più presto , e da solo la vedo dura , quindi se c'è qualcuno disposto ad aiutarmi dietro compenso, ben venga.
  • Re: Problema algoritmo lento...

    Mi dispiace, su questo non posso aiutarti. Era quello che avevi chiesto molto tempo addietro.
Devi accedere o registrarti per scrivere nel forum
31 risposte