Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Cephes/polyn/   (Cephes Mathematical Library ©)  Datei vom 12.5.2026 mit Größe 3 kB image not shown  

Quelle  euclid.c

  Sprache: 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 "mconf.h"
#ifdef ANSIPROT
extern double fabs ( double );
extern double floor ( double );
double euclid( double *, double * );
#else
double fabs(), floor(), euclid();
#endif

extern 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)
 return1.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 );
}


Messung V0.5 in Prozent
C=89 H=97 G=93

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-15) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.