Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/misc/fract.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>

/*
 *		Robert J. Craig
 * 		AT&T Bell Laboratories
 *		1200 East Naperville Road
 *		Naperville, IL 60566-7045
 *
 * Given a number, v, this function outputs two integers,
 * d and n, such that
 *
 *	v = n / d
 *
 * to accuracy
 *	epsilon = | (v - n/d) / v | <= error
 *
 * input:  v = decimal number you want replaced by fraction.
 *	  error = accuracy to which the fraction should
 *		  represent the number v.
 *
 * output:  n = numerator of representing fraction.
 *	   d = denominator of representing fraction.
 *
 * return value:  -1.0 if(v < MIN || v > MAX || error < 0.0)
 *		 | (v - n/d) / v | otherwise.
 *
 * Note:  This program only works for positive numbers, v.
 *
 * reference:  Jerome Spanier and Keith B. Oldham, "An Atlas
 *	of Functions," Springer-Verlag, 1987, pp. 665-7.
 */

#define MAX 4.0e+10
#define MIN 3.0e-10

double
frac(double v, int *n, int *d, double error)
{

	int D, N, t;
	double epsilon, r, m;


	if(v < MIN || v > MAX || error < 0.0)
		return -1.0;
	*d = D = 1;
	*n = v;
	N = *n+1;

	do{
		r = 0.0;
		if(v*(*d) != (double)*n){
			r = (N - v*D)/(v * *d - *n);
			if(r <= 1.0){
				t = N;
				N = *n;
				*n = t;
				t = D;
				D = *d;
				*d = t;
			}
		}
		print("%6d/%-6d", *n, *d);
		epsilon = fabs(1.0 - *n/(v * *d));
		if(epsilon > error){
			m = 1.0;
			do{
				m *= 10.0;
			}while (m*epsilon < 1.0);
			epsilon = 1.0/m * (int)(0.5 + m*epsilon);
		}
	
		print("	ε = %e\n", epsilon);
		if(epsilon <= error)
			break;

		if(r <= 1.0)
			r = 1.0/r;

		N += *n *(int)r;
		D += *d *(int)r;
		(*n) += N;
		(*d) += D;

	}while(r != 0.0);
	return epsilon;
}

void
main(int argc, char *argv[])
{
	int n, d;
	double error = 1.0e-10;

	if(argc != 2){
		fprint(2, "usage: fract: n\n");
		exits("usage");
	}

	frac(atof(argv[1]), &n, &d, error);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.