- Stampa di un reale enorme
void Stampa_Reale_Enorme(REALE_ENORME re)
{
int i, j;
if(re.Segno == '-')
Print_Char('-');;
for(i = 49; i >= 0 && re.Intera[i] == '0'; i--) ;
if(i == -1)
Print_Char('0');
else
for( ; i >= 0 ; i--) Print_Char(re.Intera[i]);
for(i = 49; i >= 0 && re.Decimale[i] == '0'; i--) ;
if(i != -1){
Print_Char(',');
for( j = 0; j <=i ;j++) Print_Char(re.Decimale[j]);
}
}
- Lettura di un reale enorme
REALE_ENORME Leggi_Reale_Enorme(void)
{
CIFRE cif;
int i,j;
REALE_ENORME re;
re.Segno = Get_Char();
if(re.Segno != '+' && re.Segno != '-')
printf("ERRORE: un reale non puo\' iniziare con %c \n",re.Segno);
Leggi_Cifre(cif,'\0');
/* le cifre intere sono messe in cif aggiungendo '\0' per completare
vengono poi riordinate oppurtunamente quando ricopiate in re.Intera */
for(i=49; i >= 0 && cif[i] == '\0'; i--)
re.Intera[i]= '0';
for(j = 0; i >= 0; i--,j++)
re.Intera[j] = cif[ i];
Salta(',');
Leggi_Cifre(re.Decimale,'0');
return re;
}
che utilizza la funzione ausiliaria
void Leggi_Cifre(CIFRE cif,char c)
/*legge la sequenza di cifre decimali dal file `ingresso.txt' completa
l'array con il carattere c*/
{
int i;
for(i=0; i < 50; i++)
cif[i] = c;
for(i = 0; (i < 50) && (isdigit(Look_Char())); i++)
cif[i] = Get_Char();
}
- Somma di due reali enormi
- La somma di due numeri reali enormi re1 e re2 è definita come
segue:
- se re1 e re2 hanno lo stesso segno
- segno di re1 (valore assoluto(re1) + valore assoluto(re2))
- se re1 e re2 hanno segno diverso
-
- se valore assoluto(re1) > valore assoluto(re2)
- segno di re1 (valore assoluto(re1) - valore assoluto(re2))
- se valore assoluto(re2) > valore assoluto(re1)
- segno di re2 (valore assoluto(re2) - valore assoluto(re1))
- se valore assoluto(re1) = valore assoluto(re2)
- + 0
REALE_ENORME Somma(REALE_ENORME re1, REALE_ENORME re2)
{
int j;
REALE_ENORME re;
if(re1.Segno == re2.Segno =='+'){ /*stesso segno*/
re = Somma_Pos(re1, re2);
re.Segno = re1.Segno;
}
else if(Maggiore_Assoluto(re1, re2)){ /*re1 è maggiore in valore assoluto di re2*/
re = Differenza_Pos(re1, re2);
re.Segno = re1.Segno;
}
else if(Maggiore_Assoluto(re2, re1)){ /*re2 è maggiore in valore assoluto di re*/
re = Differenza_Pos(re2, re1);
re.Segno = re2.Segno;
}
else /* re conterrà 0 */
{ re.Segno = '+';
for(j = 0; j < 50; j++)
re.Decimale[j] = re.Intera[j] = '0';
};
return re;
}
che utilizza le seguenti funzioni ausiliarie
int Maggiore_Assoluto(REALE_ENORME re1, REALE_ENORME re2)
/*vera ses re1 è maggiore strettamente di re2*/
{
int i, sono_uguali = TRUE;
for(i = 49; sono_uguali && (0 *lt;= i); i--)
if(re1.Intera[i] != re2.Intera[i])
sono_uguali = FALSE;
if(! sono_uguali)
return re1.Intera[i+1] > re2.Intera[i+1];
else{ /* controllo parti decimali*/
for(i=0; sono_uguali && i < 50; i++)
if(re1.Decimale[i] != re2.Decimale[i])
sono_uguali = FALSE;
if(! sono_uguali)
return re1.Decimale[i-1] > re2.Decimale[i-1];
else
return FALSE;
};
}
REALE_ENORME Somma_Pos(REALE_ENORME re1, REALE_ENORME re2)
{
int x, riporto = 0, i;
REALE_ENORME re;
for(i = 49; i >= 0; i--){
x = riporto + Num(re1.Decimale[i]) + Num(re2.Decimale[i]);
if(x > 9){
re.Decimale[i] = Cifra(x % 10);
riporto = 1;
}
else {
re.Decimale[i] = Cifra(x);
riporto = 0;
};
};
for(i = 0; i < 50; i++){
x = riporto + Num(re1.Intera[i]) + Num(re2.Intera[i]);
if(x > 9){
re.Intera[i] = Cifra(x % 10);
riporto = 1;
}
else {
re.Intera[i] = Cifra(x);
riporto = 0;
};
};
if(riporto == 1)
printf("OVERFLOW\n");
return re;
}
char Cifra(int n)
{
return n + '0';
}
int Num(char c)
{
return c - '0';
}
REALE_ENORME Differenza_Pos(REALE_ENORME re1, REALE_ENORME re2)
/*differenza tra due numeri positivi, quando il primo è maggiore del secondo */
{
int x, riporto = 0, i;
REALE_ENORME re;
for(i = 49 ; i >= 0; i--){
if((Num(re1.Decimale[i]) + riporto) >= Num(re2.Decimale[i])){
re.Decimale[i] = Cifra((Num(re1.Decimale[i]) + riporto) - Num(re2.Decimale[i]));
riporto = 0;
}
else{
re.Decimale[i] = Cifra((Num(re1.Decimale[i]) + riporto + 10) - Num(re2.Decimale[i]));
riporto = -1;
};
};
for(i = 0; i < 50 ; i ++){
if((Num(re1.Intera[i]) + riporto) >= Num(re2.Intera[i])){
re.Intera[i] = Cifra((Num(re1.Intera[i]) + riporto) - Num(re2.Intera[i]));
riporto = 0;
}
else{
re.Intera[i] = Cifra((Num(re1.Intera[i]) + riporto + 10) - Num(re2.Intera[i]));
riporto = -1;
};
};
if(riporto == -1)
printf("ERRORE : re1 doveva essere piu\' grande\n");
return re;
};
- Differenza di due numeri reali
REALE_ENORME Differenza(REALE_ENORME re1, REALE_ENORME re2)
{
re2.Segno = - re2.Segno;
return Somma(re1, re2);
}
- Prodotto di due numeri reali
-
Applicando la proprietà distributiva della somma rispetto al
prodotto e notando che
è uguale a
il prodotto è definito come segue:
REALE_ENORME Prodotto(REALE_ENORME re1, REALE_ENORME re2)
{
int i;
REALE_ENORME aux,aux1, re;
char seg;
/* segno*/
seg = (re1.Segno == re2.Segno) ? '+' : '-';
/*rendo re1,e re2 positivi*/
re1.Segno = re2.Segno = '+';
/* assegno 0 a re */
for(i = 0 ; i < 50; i++)
re.Intera[i] = re.Decimale[i] = '0';
/* moltiplico per cifre decimali */
for(i = 49 ; i >= 0 ; i--){
aux = Per_Scalare(re1, Num(re2.Decimale[i]));
aux1 = Per_10(aux, -(i+1));
re = Somma(re, aux1);
};
/* moltiplico per cifre intere */
for(i = 0 ; i < 50 ; i++){
aux = Per_Scalare(re1, Num(re2.Intera[i]));
aux = Per_10(aux, i);
re = Somma(re, aux);
};
re.Segno = seg;
return re;
}
REALE_ENORME Per_Scalare(REALE_ENORME re1, int n)
{
int riporto = 0, j, x;
REALE_ENORME re;
for(j = 49 ; j >= 0 ; j--){
x = riporto + (n * Num(re1.Decimale[j]));
re.Decimale[j] = Cifra(x % 10);
riporto = x / 10;
};
for(j = 0 ; j < 50 ; j++){
x = riporto + (n * Num(re1.Intera[j]));
re.Intera[j] = Cifra(x % 10);
riporto = x / 10;
};
if(riporto != 0)
printf("OVERFLOW\n");
re.Segno = re1.Segno;
return re;
}
REALE_ENORME Per_10(REALE_ENORME re1, int i)
{
REALE_ENORME re;
int j;
if(i == 0) return re1;
else if(i > 0){
/* sposto indietro le vecchie cifre intere*/
for(j = 49 - i ; j >= 0 ; j--)
re.Intera[j + i] = re1.Intera[j];
/* i cifre decimali diventano intere*/
for(j = 0; j <= i-1 ; j++)
re.Intera[(i - 1) - j] = re1.Decimale[j];
/* sposto indietro le vecchie cifre decimali*/
for(j = i; j <= 49 ; j++)
re.Decimale[j - i] = re1.Decimale[j];
/* aggiungo gli zeri decimali necessari */
for(j = (49-i) + 1; j <= 49 ; j++)
re.Decimale[j] = '0';
re.Segno = re1.Segno;
return re;
}
else /* i < 0 */
{
i = -i;
/* sposto le vecchie cifre decimali*/
for(j = 49 - i ; j >= 0 ; j--)
re.Decimale[j + i] = re1.Decimale[j];
/* i cifre intere diventano decimali*/
for(j = 0; j <= i-1 ; j++)
re.Decimale[ -j +(i -1)] = re1.Intera[j];
/* sposto le vecchie cifre intere*/
for(j = i; j <= 49 ; j++)
re.Intera[j - i] = re1.Intera[j];
/* aggiungo gli zeri interi necessari */
for(j = 49-i+1; j <= 49 ; j++)
re.Intera[j] = '0';
re.Segno = re1.Segno;
return re;
};
}
A questo punto abbiamo sviluppato due file che faranno parte del
programma, l'interfaccia e il body di questo modulo: