home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
misc
/
bignum.lzh
/
BIGNUM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-01
|
6KB
|
257 lines
/* bignum.c -- following an idea from c't-magazine 9/88
Compiler: Aztec C3.6a for Amiga using "make -f bignum.make" */
#include <stdio.h>
#define FALSCH 0
#define WAHR !FALSCH
#define USHORT unsigned short
#define ULONG unsigned long
USHORT *feld1, *feld2, *ergeb;
USHORT potenz;
main(argc,argv)
int argc;
char *argv[];
{
USHORT Groesse, Stellen;
extern USHORT *malloc();
if (argc<=1) {
printf("gewⁿnschte Anzahl Stellen: ");
scanf("%d",&Stellen);
}
else {
sscanf(argv[1],"%d",&Stellen);
};
Groesse=Stellen/4+1;
if ((feld1=malloc(Groesse*sizeof(USHORT)))==0L) {
printf("Es ist zu wenig Speicher frei !\n");
exit(30);
};
if ((feld2=malloc(Groesse*sizeof(USHORT)))==0L) {
printf("Es ist zu wenig Speicher frei !\n");
exit(30);
};
if ((ergeb=malloc(Groesse*sizeof(USHORT)))==0L) {
printf("Es ist zu wenig Speicher frei !\n");
exit(30);
};
euler(feld1, ergeb, Groesse);
printf("\n");
pi(feld1, feld2, ergeb, Groesse);
printf("\n");
/* belegten Speicher wieder freigeben */
free(feld1);
free(feld2);
free(ergeb);
exit(0);
}
/* Berechnung der Eulerschen Zahl e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! */
euler(feld1,ergeb,Groesse)
USHORT feld1[], ergeb[];
register USHORT Groesse;
{
int nicht_fertig;
register USHORT i;
register USHORT fakulz; /* FakultΣtszΣhler (n) */
/* L÷schen der Vektoren */
for (i=0; i<Groesse; i++) feld1[i]=ergeb[i]=0;
fakulz=1;
ergeb[Groesse-1]=1; /* Ergebnisvektor */
feld1[Groesse-1]=1; /* Feld1 enthaelt 1/n! */
nicht_fertig=WAHR;
/* e berechnen */
while (nicht_fertig) {
/* (1 / n!) / (n+1) = 1 / (n+1)! */
nicht_fertig=division(feld1, fakulz, Groesse);
/* 1 / (n+1)! zum alten Ergebnis addieren */
addition(ergeb,feld1,Groesse);
fakulz++;
}
printf("\ne=2,");
ausgabe(ergeb,Groesse);
}
/* Berechnung von PI */
pi(feld1,feld2,ergeb,Groesse)
USHORT feld1[],feld2[],ergeb[], Groesse;
{
register int addieren, nicht_fertig;
register USHORT i, zaehler;
for (i=0; i<Groesse; i++) feld1[i]=feld2[i]=ergeb[i]=0;
feld1[Groesse-1]=1;
zaehler = 1;
potenz = 5;
nicht_fertig=WAHR;
addieren=WAHR;
while (nicht_fertig) {
/* Ersten Term berechnen */
division(feld1, potenz, Groesse); /* durch 5 dividieren */
copy(feld1, feld2, Groesse); /* Kopie anlegen */
/* Kopie durch Zaehler (3,5,7,9) dividieren
und prⁿfen, ob Quotient bereits 0 ist */
nicht_fertig=division(feld2, zaehler, Groesse);
/* Ergebnis der Divisionen abwechselnd addieren und subtrahieren */
if (addieren) {
addition(ergeb,feld2, Groesse);
}
else {
subtraktion(ergeb,feld2, Groesse);
};
addieren= !addieren;
zaehler+=2;
/* Original noch einmal durch 5 dividieren */
division(feld1,potenz,Groesse);
};
printf("\nzaehler=%u\n",zaehler);
/* Ergebnis mit 4 multiplizieren */
addition(ergeb, ergeb, Groesse);
addition(ergeb, ergeb, Groesse);
/* Vektoren fⁿr die zweite Runde initialisieren */
for (i=0; i<Groesse; i++) feld1[i]=feld2[i]=0;
feld1[Groesse-1]=1;
potenz=239;
zaehler=1;
addieren=FALSCH;
nicht_fertig=WAHR;
while (nicht_fertig) {
/* Term in der zweiten Klammer berechnen */
division(feld1,potenz,Groesse);
copy(feld1,feld2,Groesse);
nicht_fertig=division(feld2,zaehler,Groesse);
if (addieren) {
addition(ergeb,feld2,Groesse);
}
else {
subtraktion(ergeb,feld2,Groesse);
};
addieren= !addieren;
zaehler+=2;
division(feld1,potenz,Groesse);
};
/* Ergebnis noch einmal mit 4 multiplizieren */
addition(ergeb,ergeb,Groesse);
addition(ergeb,ergeb,Groesse);
printf("zaehler=%u\n",zaehler);
printf("\nPI=3,");
ausgabe(ergeb,Groesse);
}
/* feld = feld / divisor */
division(feld, divisor, Groesse)
USHORT feld[], Groesse;
register USHORT divisor;
{
register ULONG rest, dividend;
int ergebnis_nicht_null;
register short i;
rest = 0L;
ergebnis_nicht_null=FALSCH;
for (i=Groesse-1; i>=0; i--) {
dividend=rest*10000+feld[i];
feld[i]=dividend / divisor;
if (feld[i]!=0) ergebnis_nicht_null=WAHR;
rest=dividend % divisor;
};
return(ergebnis_nicht_null);
}
/* feld = feld * faktor */
/*
multiplikation(feld,faktor,Groesse)
USHORT feld[], faktor, Groesse;
{
register short i;
register USHORT uebertrag;
register ULONG produkt;
uebertrag=0;
for (i=Groesse-1; i>=0; i--) {
produkt=feld[i]*faktor;
if (produkt>9999) {
feld[i]=(USHORT)(produkt % 10000) + uebertrag;
uebertrag=(USHORT)(produkt / 10000);
}
else {
feld[i]=(USHORT)produkt;
uebertrag=0;
};
};
}
*/
/* summe = summe + feld */
addition(summe,feld,Groesse)
USHORT summe[],feld[];
register USHORT Groesse;
{
register USHORT uebertrag,i;
uebertrag=0;
for (i=0; i<Groesse; i++) {
summe[i]+=feld[i]+uebertrag;
if (summe[i]>9999) {
summe[i]-=10000;
uebertrag=1;
}
else uebertrag=0;
};
}
/* differenz = differenz - feld */
subtraktion(differenz,feld,Groesse)
USHORT differenz[], feld[];
register USHORT Groesse;
{
register USHORT uebertrag, i;
/* Neunerkomplement von Feld berechnen */
for (i=0; i<Groesse; i++) feld[i]=9999-feld[i];
/* Eins addieren --> ergibt Zehnerkomplement */
uebertrag=1;
i=0;
while ((uebertrag==1) && (i<Groesse)) {
feld[i]+=uebertrag;
if (feld[i] > 9999) {
feld[i]-=10000;
uebertrag=1;
}
else uebertrag=0;
i++;
};
/* Zehnerkomplement zu Differenz addieren */
addition(differenz, feld, Groesse);
}
copy(original, kopie, Groesse)
USHORT original[], kopie[];
register USHORT Groesse;
{
register USHORT i;
for (i=0; i<Groesse; i++) kopie[i]=original[i];
}
ausgabe(ergeb,Groesse) /* Ergebnis ausgeben */
USHORT ergeb[];
register USHORT Groesse;
{
char zeichen[5];
register short i,j;
zeichen[4]=NULL;
for (i=Groesse-2; i>=0; i--) {
for (j=0; j<4; j++) {
zeichen[3-j]= (ergeb[i] % 10) + '0';
ergeb[i]/=10;
};
printf("%4s",zeichen);
};
}