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