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

📄 pi.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* pI.c */

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


#ifndef DEBUG

POLYI BANKI = NULL;

#endif

#ifndef DEBUG
void SAVEI(Ptr)
POLYI Ptr;
/*
This routine takes a POLYI (which is a linked list of TERMI's) that is
no longer needed, and links it onto the start of the free list BANKI,
which itself is just a linked list opf TERMI's.
*/
{
	POLYI tmp;

	tmp=Ptr;
	while(tmp->NEXT)
	  tmp=tmp->NEXT;
	tmp->NEXT = BANKI;
	BANKI = Ptr;
	Ptr = NULL;
}
#endif

POLYI CREATEPI()
/*
 * If there is anything in BANKI (the memory bank of TERMI's) then use that,
 * otherwise allocate a new one.
 * No initialisation is performed
*/
{
	POLYI Ptr;
	#ifndef DEBUG
	if (BANKI)
	{
		Ptr = BANKI;
		BANKI = BANKI->NEXT;
	}
	else
	#endif
	Ptr = (POLYI)mmalloc(sizeof(struct TERMI));
	return (Ptr);	
}

int DEGREEPI(POLYI Pptr)
/*
 * returns the degree of the polynomial Pptr.
 */
{
	if (Pptr == NULL)
		return (-1);
	else
		return (Pptr->DEG);
}

MPI *LEADPI(POLYI Pptr)
/*
 * *Aptr is the  leading coefficient of the polynomial Pptr.
 */
{
	if (Pptr == NULL)
		return ZEROI();
	else
		return COPYI(Pptr->COEF);
}

void DELETEPI(POLYI Pptr)
/*
 * returns back to the system storage dynamically allocated to the linked list
 * which Pptr points to.
 */
{
	POLYI Qtmp, orig;
	
	if(!Pptr) return;
	orig = Pptr;
	while (Pptr != NULL)
	{
 		Qtmp = Pptr->NEXT;
		FREEMPI(Pptr->COEF);
#ifdef DEBUG /* This fix was due to Peter Adams on 30/6/94 */
		SAVEPI(Pptr);
#endif
		Pptr= Qtmp;
	}
#ifndef DEBUG
	SAVEPI(orig);
#endif
	return;
}

void PINSERTPI(int DEG, MPI *COEF, POLYI *Pptr, USI OPT)
/*
 * inserts a copy of a single term *Qptr into polynomial *Pptr.
 * It has two options that control the insertion in case a term of *Pptr already
 * has the degree of *Qptr, If OPT = 0, then the term is replaced; if OPT = 1,
 * then the coefficient of *Qptr is added to that of the corresponding term of
 *  *Pptr.
 */
{
	POLYI CURSOR, Ttmp;
	MPI *TempI;

	if (*Pptr == NULL)
	{
		*Pptr = CREATEPI();
		(*Pptr)->DEG = DEG;
		(*Pptr)->COEF = COPYI(COEF);
		(*Pptr)->NEXT = NULL;
		return;
	}
	else
	{
		CURSOR = *Pptr;
		while ((CURSOR->DEG > DEG) && (CURSOR->NEXT != NULL))
			CURSOR = CURSOR->NEXT;
		if (CURSOR->DEG < DEG)
		{
			/* Qptr inserted before CURSOR */
			Ttmp = CREATEPI();
			Ttmp->DEG = CURSOR->DEG;
			Ttmp->COEF = CURSOR->COEF;
			Ttmp->NEXT = CURSOR->NEXT;
			CURSOR->DEG = DEG;
			CURSOR->COEF = COPYI(COEF);
			CURSOR->NEXT = Ttmp;
			return;
		}
		else if (CURSOR->DEG == DEG)
		{
			if (OPT == 0)
				CURSOR->COEF = COPYI(COEF);
			else
			{
				TempI = CURSOR->COEF;
				CURSOR->COEF = ADDI(CURSOR->COEF, COEF);
				FREEMPI(TempI);
			}
			return;
		}
		else
		{
			/* CURSOR->DEG > Qptr->DEG and CURSOR->NEXT === NULL */
			/* Qptr inserted at end */
			Ttmp = CREATEPI();
			Ttmp->DEG = DEG;
			Ttmp->COEF = COPYI(COEF);
			Ttmp->NEXT = NULL;
			CURSOR->NEXT = Ttmp;
			return;
		}
	}
}

void PURGEPI(POLYI *Pptr)
/*
 * gets rid of any zero coefficients in the polynomial Pptr.
 */
{
	POLYI R1tmp, R2tmp;

	if (*Pptr != NULL)
	{
		R1tmp = *Pptr;
		R2tmp = (*Pptr)->NEXT;
		while (R2tmp != NULL)
		{
			/* purge non-leading terms */
			if ((R2tmp->COEF)->S == 0)
			{
				R1tmp->NEXT = R2tmp->NEXT;
				R2tmp->NEXT = NULL;
				DELETEPI(R2tmp);
				R2tmp = R1tmp->NEXT;
			}
			else
			{
				R1tmp = R2tmp;
				R2tmp = R2tmp->NEXT;
			}
		}
		if (((*Pptr)->COEF)->S == 0)
		{
			/* purge leading term */
			R1tmp = *Pptr;
			*Pptr = (*Pptr)->NEXT;
			R1tmp->NEXT = NULL;
			DELETEPI(R1tmp);
		}
	}
	return;
}

POLYI COPYPI(POLYI Pptr)
/*
 * makes a copy of the polynomial Pptr.
 */
{
	POLYI Rtmp, Sptr;

	Sptr = NULL;
	Rtmp = Pptr;
	while (Rtmp != NULL)
	{
		PINSERTPI(Rtmp->DEG, Rtmp->COEF, &Sptr, 0);
		Rtmp = Rtmp->NEXT;
	}
	return (Sptr);
}
 
void PRINTPI(POLYI Pptr)
{
  FPRINTPI(stdout, Pptr);
}

void FPRINTPI(FILE *outfile, POLYI Pptr)
/*
 * outputs the terms of the polynomial Pptr.
 */
{
	POLYI CURSOR;
	int k, l;

	if (Pptr == NULL)
	{
		fprintf(outfile, "0");
		return;
	}
	else
	{
		CURSOR = Pptr;
		k = DEGREEPI(Pptr);
		while (CURSOR != NULL)
		{
			l = (CURSOR->COEF)->S;
			if (l == -1)
			{
				(CURSOR->COEF)->S = 1;
				fprintf(outfile, "- ");
			}
			else
			{
				if (CURSOR->DEG != k)
					fprintf(outfile, "+ ");
			}
			if (CURSOR->DEG == 0 || !EQONEI(CURSOR->COEF))
				FPRINTI(outfile, CURSOR->COEF);
			if (l == -1)
				(CURSOR->COEF)->S = -1;
			if (CURSOR->DEG == 1)
				fprintf(outfile, "X");
			if (CURSOR->DEG > 1)
				fprintf(outfile, "X^%d", CURSOR->DEG);
			if (CURSOR->NEXT != NULL)
				fprintf(outfile, " ");
			CURSOR = CURSOR->NEXT;
		}
		return;
	}
}



POLYI SCALARPI(MPI *Cptr, POLYI Pptr)
/*
 * multiplying the polynomial Pptr by the MPI *Cptr.
 */
{
	POLYI Sptr, Rtmp;
	MPI *TempI;

	if (Pptr == NULL || Cptr->S == 0)
		Sptr = NULL;
	else
	{
		Sptr = COPYPI(Pptr);
		Rtmp = Sptr;
		while (Rtmp != NULL)
		{
			TempI = Rtmp->COEF;
			Rtmp->COEF = MULTI(Rtmp->COEF, Cptr);
			FREEMPI(TempI);
			Rtmp = Rtmp->NEXT;
		}
	}
	return (Sptr);
}

POLYI ADDPI(POLYI Pptr, POLYI Qptr)
/*
 * returns the sum of two polynomials.
 */
{
	POLYI CURSOR, Sptr;

		Sptr = COPYPI(Pptr);
		CURSOR = Qptr;
		while (CURSOR != NULL)
		{
			PINSERTPI(CURSOR->DEG, CURSOR->COEF, &Sptr, 1);
			CURSOR = CURSOR->NEXT;
		}
		PURGEPI(&Sptr);
		return (Sptr);
}

POLYI SUBPI(POLYI Pptr, POLYI Qptr)
/*
 * returns the difference Pptr - Qptr of two polynomials.
 */
{
	POLYI CURSOR, Sptr;
	MPI *TempI;

		Sptr = COPYPI(Pptr);
		if (Qptr == NULL)
			return (Sptr);
		CURSOR = Qptr;
		while (CURSOR != NULL)
		{
			TempI = MINUSI(CURSOR->COEF);
			PINSERTPI(CURSOR->DEG, TempI, &Sptr, 1);
			FREEMPI(TempI);
			CURSOR = CURSOR->NEXT;
		}
		PURGEPI(&Sptr);
		return (Sptr);
}

POLYI MULTPI(POLYI Pptr, POLYI Qptr)
/*
 * returns the product of two polynomials.
 */
{
	POLYI Sptr, CURSOR_P, CURSOR_Q;
	MPI *TempI;
	int k;

	if (Pptr == NULL || Qptr == NULL)
		return (NULL);
	Sptr = NULL;
	CURSOR_P = Pptr;
	while (CURSOR_P != NULL)
	{
		CURSOR_Q = Qptr;
		while (CURSOR_Q != NULL)
		{
			k = CURSOR_P->DEG + CURSOR_Q->DEG;
			TempI = MULTI(CURSOR_P->COEF, CURSOR_Q->COEF);
			PINSERTPI(k, TempI, &Sptr, 1);
			FREEMPI(TempI);
			CURSOR_Q = CURSOR_Q->NEXT;
		}
		CURSOR_P = CURSOR_P->NEXT;
	}
	PURGEPI(&Sptr);
	return (Sptr);
}

MPI *VALPI(POLYI Pptr, MPI *Cptr)
/*
 * Evaluating the polynomial Pptr at the MPI *Cptr.
 */
{
	int k;
	MPI *B, *Aptr, *TempI;
	POLYI CURSOR;

	if (Pptr == NULL)
		return ZEROI();
	else
		Aptr = COPYI(Pptr->COEF);
	CURSOR = Pptr;
	while (CURSOR != NULL)
	{
		if (CURSOR->NEXT == NULL)
			k = DEGREEPI(CURSOR);
		else
			k = DEGREEPI(CURSOR) - DEGREEPI(CURSOR->NEXT);
		B = POWERI(Cptr, (unsigned int)k);
		TempI = Aptr;
		Aptr = MULTI(Aptr, B);
		FREEMPI(B);
		FREEMPI(TempI);
		CURSOR = CURSOR->NEXT;
		if (CURSOR != NULL)
		{
			TempI = Aptr;
			Aptr = ADDI(Aptr, CURSOR->COEF);
			FREEMPI(TempI);
		}
	}
	return (Aptr);
}

POLYI DIVPI(POLYI Fptr, POLYI Gptr)
/*
 * Pseudo-division of polynomials: see Knuth, Vol 2, p.407 
 * and H. Flanders, Scientific Pascal, p.510.
 */
{
	POLYI F, Tmp, Htmp, CURSOR, Qptr;
	int j, d;
	MPI *A, *G, *TempI;

	Qptr = NULL;
	d = DEGREEPI(Gptr);
	j = DEGREEPI(Fptr) - d;
	if (j < 0)
		return (Qptr);
	else
	{
		F = COPYPI(Fptr);
		G = LEADPI(Gptr);
		A = POWERI(G, (unsigned int)(j + 1));
		Tmp = F;
		F = SCALARPI(A, Tmp);
		FREEMPI(A);
		DELETEPI(Tmp);
		while ((j = DEGREEPI(F)) >= d)
		{
			j = j - d;
			A = LEADPI(F);
			TempI = A;
			A = INTI(A, G);
			FREEMPI(TempI);
			Htmp = COPYPI(Gptr);
			CURSOR = Htmp;
			do
			{
				CURSOR->DEG = j + CURSOR->DEG;
				TempI = CURSOR->COEF;
				CURSOR->COEF = MINUSI(CURSOR->COEF);
				FREEMPI(TempI);
				TempI = CURSOR->COEF;
				CURSOR->COEF = MULTI(CURSOR->COEF, A);
				FREEMPI(TempI);
				CURSOR = CURSOR->NEXT;
			}
			while (CURSOR != NULL);
			Tmp = F;
			F = ADDPI(Tmp, Htmp);
			DELETEPI(Tmp);
			DELETEPI(Htmp);
			PINSERTPI(j, A, &Qptr, 0);
			FREEMPI(A);
		}
		DELETEPI(F);
		FREEMPI(G);
		return (Qptr);
	}
}

POLYI MODPI(POLYI Fptr, POLYI Gptr)
/*
 * Pseudo-division of polynomials: see Knuth, Vol 2, p.407 
 * and H. Flanders, Scientific Pascal, p.510.
 * NOTE: This returns a polynomial that is a POSITIVE multiple of the true remainder.
 * i.e. The sign of the remainder is correct. 
 */
{
	POLYI F, Tmp, Htmp, CURSOR;
	int j, d, degDiff;
	MPI *A, *G, *Temp1I, *Temp2I;

	d = DEGREEPI(Gptr); /* n */
	j = DEGREEPI(Fptr) - d; /* m - n */
	degDiff=j;
	F = COPYPI(Fptr);	
	if (j < 0)
		return (F);
	else
	{
		G = LEADPI(Gptr);
		A = POWERI(G, (unsigned int)(j + 1));
		Tmp = F;
		F= SCALARPI(A, Tmp);
		FREEMPI(A);
		DELETEPI(Tmp);
		while ((j = DEGREEPI(F)) >= d)
		{
			j = j - d;
			A = LEADPI(F);
			if (!EQONEI(G))
			{
				Temp2I = A;
				A = INTI(A, G);
				FREEMPI(Temp2I);
			}
			Htmp = COPYPI(Gptr);
			CURSOR = Htmp;
			do
			{
				CURSOR->DEG = j + CURSOR->DEG;
				Temp1I = CURSOR->COEF;
				CURSOR->COEF = MINUSI(CURSOR->COEF);
				FREEMPI(Temp1I);
				Temp1I = CURSOR->COEF;
				CURSOR->COEF = MULTI(CURSOR->COEF, A);
				FREEMPI(Temp1I);
				CURSOR = CURSOR->NEXT;
			}
			while (CURSOR != NULL);
			Tmp = F;
			F= ADDPI(Tmp, Htmp);
			DELETEPI(Tmp);
			DELETEPI(Htmp);
			FREEMPI(A);
		}
		
		if ((degDiff % 2 == 0) && G->S == -1) {
		  POLYI TMPI;
		  TMPI = F;
		  F = MINUSPI(F);
		  DELETEPI(TMPI);
		  }	
		FREEMPI(G);
		return (F);
	}
}

MPI *CONTENTPI(POLYI Pptr)
/*
 * *Cptr is the (positive) content of the polynomial Pptr.
 */
{
	POLYI CURSOR;
	MPI *TempI, *Cptr;

	if (Pptr == NULL)
		return (ZEROI());
	else if (Pptr->DEG == 0)
	{
		Cptr = COPYI(Pptr->COEF);
		if (Cptr->S == -1)
			Cptr->S = 1;
		return (Cptr);
	}
	else
	{
		CURSOR = Pptr;
		Cptr = COPYI(CURSOR->COEF);
		if (CURSOR->NEXT != NULL)
		{
			do
			{
				TempI = Cptr;

⌨️ 快捷键说明

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