From bd82d030011cd8b9655e5ded6b6df9343b42a6bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 4 Feb 2015 14:09:54 +0100 Subject: Imported Upstream version 3.22 --- assorted/tofrac.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 assorted/tofrac.c (limited to 'assorted/tofrac.c') diff --git a/assorted/tofrac.c b/assorted/tofrac.c new file mode 100644 index 0000000..e4c1480 --- /dev/null +++ b/assorted/tofrac.c @@ -0,0 +1,71 @@ +/* + * libHX/assorted/tofrac.c + * Copyright Jan Engelhardt, 1999-2010 + * + * This file is part of libHX. libHX is free software; you can + * redistribute it and/or modify it under the terms of the GNU Lesser + * General Public License as published by the Free Software Foundation; + * either version 2.1 or (at your option) any later version. + */ +/* + * Calculates a readable fraction (i.e. 1/3) from arg and puts the + * *numerator into num, the denominator into *denom. Since the fraction + * is found out by an iterative loop, you can specify the minimum value + * of the denominator in *num and the maximum value of the denominator + * into *denom before calling the function. + * + * If a suitable fraction has been found (within the range of the + * minimum / maximum denominator, *num and *denom will be overwritten + * with the results and true is returned; false for no success. + * + * You need to re-put your min/max denom values into *num and *denom + * then. + */ +#include +#include +#include +#include +#include +#include + +/* This simplistic version does not deal with negative numbers. */ + +static bool HX_tofrac(double arg, unsigned long *num, unsigned long *denom) +{ + unsigned long i, min_denom = *num, max_denom = *denom; + double j, s; + + /* + * This tries all possible denominators until @arg multiplied by @i + * gives a number that has a fractional part of 0, which is when we + * found the optimal fraction. + */ + for (i = min_denom; i < max_denom; ++i) { + s = arg * i; + modf(s, &j); + if (s == j) { + *num = j; + *denom = i; + return true; + } + } + return false; +} + +int main(int argc, const char **argv) +{ + unsigned long d = 1, n = ULONG_MAX; + + if (argc < 2) { + fprintf(stderr, "Usage: %s 3.141592\n", *argv); + return EXIT_FAILURE; + } + + if (!HX_tofrac(strtod(argv[1], NULL), &d, &n)) { + fprintf(stderr, "Our algorithm was too weak :-)\n"); + return EXIT_FAILURE; + } + + printf("%lu/%lu\n", d, n); + return EXIT_SUCCESS; +} -- cgit v1.2.3