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

📄 euclid.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
字号:
/*							euclid.c * *	Rational arithmetic routines * * * * SYNOPSIS: * *  * typedef struct *      { *      double n;  numerator *      double d;  denominator *      }fract; * * radd( a, b, c )      c = b + a * rsub( a, b, c )      c = b - a * rmul( a, b, c )      c = b * a * rdiv( a, b, c )      c = b / a * euclid( &n, &d )     Reduce n/d to lowest terms, *                      return greatest common divisor. * * Arguments of the routines are pointers to the structures. * The double precision numbers are assumed, without checking, * to be integer valued.  Overflow conditions are reported. */ #include <math.h>#ifdef ANSIPROTextern double fabs ( double );extern double floor ( double );double euclid( double *, double * );#elsedouble fabs(), floor(), euclid();#endifextern double MACHEP;#define BIG (1.0/MACHEP)typedef struct	{	double n; /* numerator */	double d; /* denominator */	}fract;/* Add fractions. */void radd( f1, f2, f3 )fract *f1, *f2, *f3;{double gcd, d1, d2, gcn, n1, n2;n1 = f1->n;d1 = f1->d;n2 = f2->n;d2 = f2->d;if( n1 == 0.0 )	{	f3->n = n2;	f3->d = d2;	return;	}if( n2 == 0.0 )	{	f3->n = n1;	f3->d = d1;	return;	}gcd = euclid( &d1, &d2 ); /* common divisors of denominators */gcn = euclid( &n1, &n2 ); /* common divisors of numerators *//* Note, factoring the numerators * makes overflow slightly less likely. */f3->n = ( n1 * d2 + n2 * d1) * gcn;f3->d = d1 * d2 * gcd;euclid( &f3->n, &f3->d );}/* Subtract fractions. */void rsub( f1, f2, f3 )fract *f1, *f2, *f3;{double gcd, d1, d2, gcn, n1, n2;n1 = f1->n;d1 = f1->d;n2 = f2->n;d2 = f2->d;if( n1 == 0.0 )	{	f3->n = n2;	f3->d = d2;	return;	}if( n2 == 0.0 )	{	f3->n = -n1;	f3->d = d1;	return;	}gcd = euclid( &d1, &d2 );gcn = euclid( &n1, &n2 );f3->n = (n2 * d1 - n1 * d2) * gcn;f3->d = d1 * d2 * gcd;euclid( &f3->n, &f3->d );}/* Multiply fractions. */void rmul( ff1, ff2, ff3 )fract *ff1, *ff2, *ff3;{double d1, d2, n1, n2;n1 = ff1->n;d1 = ff1->d;n2 = ff2->n;d2 = ff2->d;if( (n1 == 0.0) || (n2 == 0.0) )	{	ff3->n = 0.0;	ff3->d = 1.0;	return;	}euclid( &n1, &d2 ); /* cross cancel common divisors */euclid( &n2, &d1 );ff3->n = n1 * n2;ff3->d = d1 * d2;/* Report overflow. */if( (fabs(ff3->n) >= BIG) || (fabs(ff3->d) >= BIG) )	{	mtherr( "rmul", OVERFLOW );	return;	}/* euclid( &ff3->n, &ff3->d );*/}/* Divide fractions. */void rdiv( ff1, ff2, ff3 )fract *ff1, *ff2, *ff3;{double d1, d2, n1, n2;n1 = ff1->d;	/* Invert ff1, then multiply */d1 = ff1->n;if( d1 < 0.0 )	{ /* keep denominator positive */	n1 = -n1;	d1 = -d1;	}n2 = ff2->n;d2 = ff2->d;if( (n1 == 0.0) || (n2 == 0.0) )	{	ff3->n = 0.0;	ff3->d = 1.0;	return;	}euclid( &n1, &d2 ); /* cross cancel any common divisors */euclid( &n2, &d1 );ff3->n = n1 * n2;ff3->d = d1 * d2;/* Report overflow. */if( (fabs(ff3->n) >= BIG) || (fabs(ff3->d) >= BIG) )	{	mtherr( "rdiv", OVERFLOW );	return;	}/* euclid( &ff3->n, &ff3->d );*/}/* Euclidean algorithm *   reduces fraction to lowest terms, *   returns greatest common divisor. */double euclid( num, den )double *num, *den;{double n, d, q, r;n = *num; /* Numerator. */d = *den; /* Denominator. *//* Make numbers positive, locally. */if( n < 0.0 )	n = -n;if( d < 0.0 )	d = -d;/* Abort if numbers are too big for integer arithmetic. */if( (n >= BIG) || (d >= BIG) )	{	mtherr( "euclid", OVERFLOW );	return(1.0);	}/* Divide by zero, gcd = 1. */if(d == 0.0)	return( 1.0 );/* Zero. Return 0/1, gcd = denominator. */if(n == 0.0)	{/*	if( *den < 0.0 )		*den = -1.0;	else		*den = 1.0;*/	*den = 1.0;	return( d );	}while( d > 0.5 )	{/* Find integer part of n divided by d. */	q = floor( n/d );/* Find remainder after dividing n by d. */	r = n - d * q;/* The next fraction is d/r. */	n = d;	d = r;	}if( n < 0.0 )	mtherr( "euclid", UNDERFLOW );*num /= n;*den /= n;return( n );}

⌨️ 快捷键说明

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