⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i5r.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* i5R.c */
/* programs for doing arithmetic with MPR's. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "integer.h"
#include "fun.h"

#ifdef DEBUG
extern long int nettbytes;
#endif

MPR *BUILDMPR( )
/*
 * mallocs space for an MPR.
 */
{
	MPR *Mptr;

	Mptr = (MPR *)mmalloc((USL)sizeof(MPR));
	return (Mptr);
}

void FREEMPR(MPR *Mptr)
/*
 * deallocates the space alloted for the MPR Mptr.
 */
{
	if (Mptr == NULL)
		return;
	FREEMPI(Mptr->N);
	FREEMPI(Mptr->D);
	ffree ((char *)Mptr, sizeof(MPR));
	return;
}

MPR *COPYR(MPR *Aptr)
/*
 * returns a pointer to a copy of *Aptr.
 */
{
	MPR *Bptr;
	Bptr = BUILDMPR();
	Bptr->N = COPYI(Aptr->N);
	Bptr->D = COPYI(Aptr->D);
	return (Bptr);
}

unsigned int EQUALR(MPR *Aptr, MPR *Bptr)
/*
 * returns 1 if *Aptr = *Bptr, 0 otherwise.
 */
{
	if (EQUALI(Aptr->N, Bptr->N) * EQUALI(Aptr->D, Bptr->D))
		return (1);
	else
		return (0);
}

MPR *MINUSR(MPR *Aptr)
/*
 * *Bptr = -(*Aptr).
 */
{
	MPR *Bptr;

	Bptr = BUILDMPR();
	Bptr->N = MINUSI(Aptr->N);
	Bptr->D = COPYI(Aptr->D);
	return (Bptr);
}

MPR *RATIOI(MPI *Aptr, MPI *Bptr)
/*
 * *Cptr = (*Aptr) / (*Bptr).
 */
{
	MPI *G;
	MPR *Cptr;

	Cptr = BUILDMPR();
	G = GCD(Aptr, Bptr);
	Cptr->N = INT(Aptr, G);
	Cptr->D = INT(Bptr, G);
	if ((Cptr->D)->S == -1)
	{
		(Cptr->D)->S = 1;
		(Cptr->N)->S = -((Cptr->N)->S);
	}
	FREEMPI(G);
	return (Cptr);
}

unsigned long LENGTHR(MPR *Mptr)
/*
 * returns the sum of the lengths of numerator and denominator + 1,
 * if Mptr is not an integer, otherwise returns the length of *Mptr.
 */
{
	if ((Mptr->D)->D || (Mptr->D)->V[0] > 1)
		return (LENGTHI(Mptr->N) + LENGTHI(Mptr->D) + 1);
	else
		return (LENGTHI(Mptr->N));
}

MPR *FINPUTR(FILE *f, unsigned int *uptr)
/*
 * Converts the ratio of two decimal inputs from stream into an MPR. 
 * *uptr =  0 if input fails, 1 if successful.
 */
{
	int t,  c;
	MPI *G, *H;
	MPR *Aptr;

	G = FINPUTI(f, uptr);
	if (*uptr == 0)
	{
		FREEMPI(G);
		return ZEROR();
	}
	t = c = fgetc(f);
	while (c == ' ')
		c = fgetc(f);
	if (c != '\n' && c != '/' && c != 'i'  && c != '+' && c != '-' && (c < '0' || c > '9'))
	{
		printf("inside INPUTSR: illegal character %c encountered:\n", c);
		FREEMPI(G);
		*uptr = 0;
		return ZEROR();
	}
	if (c == '/')
        {
	 	H = FINPUTI(f, uptr);
		if (*uptr == 0)
		{
			FREEMPI(G);
			FREEMPI(H);
			return ZEROR();
		}
		else if (H->S == 0)
		{
			printf("zero denominator entered\n");
			*uptr = 0;
			FREEMPI(G);
			FREEMPI(H);
			return ZEROR();
		}
		else
		{
			Aptr = RATIOI(G, H);
			FREEMPI(G);
			FREEMPI(H);
			c = fgetc(f);
			if (c != '\n')
				ungetc(c, f);
		}
	}
        else 
	{
		if (c != '\n' || t == ' ')
			ungetc(c, f);
		Aptr = BUILDMPR();
		Aptr->N = G;
		Aptr->D = ONEI();
	}
	return (Aptr);
}

MPR *INPUTR(unsigned int *uptr)
{
	return FINPUTR(stdin, uptr);
}

MPR *INPUTSR(char **ptr, unsigned int *uptr)
/*
 * Converts the ratio of two decimal inputs from stream into an MPR. 
 * *uptr = 0 if input fails, 1 if successful. For use with complex rationals.
 */
{
	char t;
	MPI *G, *H;
	MPR *Aptr;

	G = INPUTSI(ptr, uptr);
	if (*uptr == 0) 
	{
		FREEMPI(G);
		return ZEROR();
	}
	t = **ptr;
	while (**ptr == ' ')
		(*ptr)++;
	if (**ptr != '\0' && **ptr != '/' && **ptr != 'i'  && **ptr != '+' && **ptr != '-' && (**ptr < '0' || **ptr > '9'))
	{
		printf("inside INPUTSR: illegal character %c entered:\n", **ptr);
		*uptr = 0;
		FREEMPI(G);
		return ZEROR();
	}
	else if (**ptr == '/')
	{
		(*ptr)++;
		H = INPUTSI(ptr, uptr);
		if (*uptr == 0)
		{
			FREEMPI(G);
			FREEMPI(H);
			return ZEROR();
		}
		else if (H->S == 0)
		{
			printf("zero denominator entered\n");
			*uptr = 0;
			FREEMPI(G);
			FREEMPI(H);
			return ZEROR();
		}
		else
		{
			Aptr = RATIOI(G, H);
			FREEMPI(G);
			FREEMPI(H);
		}
	}
	else
	{
		if (t == ' ')
			(*ptr)--;
		Aptr = BUILDMPR();
		Aptr->N = G;
		Aptr->D = ONEI();
	}
	return (Aptr);
}

void FPRINTR(FILE *outfile, MPR *Aptr)
/*
 * prints the MPR *Aptr as (Aptr->N)/(Aptr->D). 
 */
{
	FPRINTI(outfile, Aptr->N);
	if ((Aptr->D)->D || (Aptr->D)->V[0] > 1)
	{
		fprintf(outfile, "/");
		FPRINTI(outfile, Aptr->D);
	}
	return;
}

void PRINTR(MPR *Aptr)
{
	FPRINTR(stdout, Aptr);
	return;
}

MPR *ZEROR()
/*
 * Returns the MPR ZERO.
 */
{
	MPR *Eptr;

	Eptr = BUILDMPR();
	Eptr->N = ZEROI();
	Eptr->D = ONEI();
	return Eptr;
}

MPR *ONER()
/*
 * Returns the MPR ONE.
 */
{
	MPR *Eptr;

	Eptr = BUILDMPR();
	Eptr->N = ONEI();
	Eptr->D = ONEI();
	return Eptr;
}

MPR *TWOR()
     /* Returns the MPR TWO */
{
  MPR *Eptr;
  Eptr = BUILDMPR();
  Eptr->N = TWOI();
  Eptr->D = ONEI();
  return Eptr;
}
MPR *MINUS_ONER()
/*
 * Returns the MPR MINUS_ONE.
 */
{
	MPR *Eptr;

	Eptr = BUILDMPR();
	Eptr->N = MINUS_ONEI();
	Eptr->D = ONEI();
	return (Eptr);
}

void SPRINTR(char *buffer, MPR *Aptr)
/*
 * prints the MPR *Aptr as (Aptr->N)/(Aptr->D). 
 */
{
	SPRINTI(buffer, Aptr->N);
	if ((Aptr->D)->D || (Aptr->D)->V[0] > 1)
	{
		buffer += strlen(buffer);
		sprintf(buffer, "/");
		SPRINTI(buffer + 1, Aptr->D);
	}
	return;
}

void FPRINTDR(FILE *outfile, unsigned int d, MPR *Mptr)
/*
 * prints *Mptr truncated to d (>= 1) decimal places to outfile.
 */
{
	int s;
	unsigned int i;
	unsigned long l;
	MPI *F, *G, *TempI;
	MPR *X, *TempR;

	s = (Mptr->N)->S;
	X = COPYR(Mptr);
	if (s == -1)
	{
		TempR = X;
		X = MINUSR(X);	
		FREEMPR(TempR);
	}
	G = INT0(X->N, X->D);
	if (s == -1)
		fprintf(outfile, "-");
	FPRINTI(outfile, G);
	fprintf(outfile, ".");
	FREEMPI(G);
	G = MOD0(X->N, X->D);
	F = POWER_I(10L, d);
	TempI = F;
	F = MULTI(F, G);
	FREEMPI(TempI);
	TempI = G;
	G = INT0(F, X->D);
	FREEMPI(F);
	FREEMPI(TempI);
	l = LENGTHI(G);
	for (i = 1; i <= d - l; i++)
		fprintf(outfile, "0");
	FPRINTI(outfile, G);
	FREEMPI(G);
	FREEMPR(X);
	return;
}

void PRINTDR(unsigned int d, MPR *Mptr)
/*
 * prints *Mptr truncated to d (>= 1) decimal places to stdout.
 */
{
	FPRINTDR(stdout, d, Mptr);
	return;
}

void SPRINTDR(char *buffer, unsigned int d, MPR *Mptr)
/*
 * prints *Mptr truncated to d (>= 1) decimal places to buffer.
 */
{
	int s;
	unsigned int i;
	unsigned long l;
	MPI *F, *G, *TempI;
	MPR *X, *TempR;

	s = (Mptr->N)->S;
	X = COPYR(Mptr);
	if (s == -1)
	{
		TempR = X;
		X = MINUSR(X);	
		FREEMPR(TempR);
	}
	G = INT0(X->N, X->D);
	if (s == -1)
	{
		sprintf(buffer, "-");
		buffer++;
	}
	SPRINTI(buffer, G);
	buffer += strlen(buffer);
	sprintf(buffer, ".");
	buffer++;
	FREEMPI(G);
	G = MOD0(X->N, X->D);
	F = POWER_I(10L, d);
	TempI = F;
	F = MULTI(F, G);
	FREEMPI(TempI);
	TempI = G;
	G = INT0(F, X->D);
	FREEMPI(TempI);
	FREEMPI(F);
	l = LENGTHI(G);
	for (i = 1; i <= d - l; i++)
	{
		sprintf(buffer, "0");
		buffer++;
	}
	SPRINTI(buffer, G);
	FREEMPI(G);
	FREEMPR(X);
}

unsigned long LENGTHDR(unsigned int d, MPR *Mptr)
/*
 * returns LENGTHI(int(*Mptr)) + d + 1, if *Mptr >= 0.
 * returns LENGTHI(int(abs(*Mptr))) + d + 2, if *Mptr < 0.
 */
{
	int s;
	unsigned long l;
	MPI *G;
	MPR *X, *TempR;

	s = (Mptr->N)->S;
	X  = COPYR(Mptr);
	if (s == -1)
	{
		TempR = X;
		X = MINUSR(X);	
		FREEMPR(TempR);
	}
	G = INT0(X->N, X->D);
	l = LENGTHI(G);
	FREEMPR(X);
	FREEMPI(G);
	if (s == -1)
		return (l + d + (USL)2);
	else
		return (l + d + (USL)1);
}

MPR *RECIPROCAL(unsigned long n)
/*
 * input: unsigned int n, 0 < n < R0, output:  MPR *Aptr = 1 / n. 
 */
{
	MPR *Aptr;

	Aptr = BUILDMPR();
	Aptr->N = ONEI();
	Aptr->D = CHANGE(n);
	return (Aptr);
}

MPR *ADDR(MPR *Aptr, MPR *Bptr)
/*
 * *Eptr = *Aptr + *Bptr.
 * P. Henrici's method: see Computer Algebra Symbolic and Algebraic
 * Computation, Springer 1982,p. 200.
 */
{
	MPI *D, *E, *R, *S, *T1, *T2, *X, *Y;
	MPR *Eptr;

	if ((Aptr->N)->S == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -