From: ellson Date: Wed, 19 Dec 2007 19:20:50 +0000 (+0000) Subject: new function: int gvprintnum(char *buf, double num); X-Git-Tag: LAST_LIBGRAPH~32^2~4972 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68ab84e140c205c35473f5bcfe1bb5e1bad8447c;p=graphviz new function: int gvprintnum(char *buf, double num); prints doubles as: fixed point, 2 decimal places, trailing zeroes suppressed --- diff --git a/lib/gvc/gvprintnum.c b/lib/gvc/gvprintnum.c new file mode 100644 index 000000000..3a3c7a77f --- /dev/null +++ b/lib/gvc/gvprintnum.c @@ -0,0 +1,114 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/*********************************************************** + * This software is part of the graphviz package * + * http://www.graphviz.org/ * + * * + * Copyright (c) 1994-2004 AT&T Corp. * + * and is licensed under the * + * Common Public License, Version 1.0 * + * by AT&T Corp. * + * * + * Information and Software Systems Research * + * AT&T Research, Florham Park NJ * + ***********************************************************/ + +/* Test with: + * cc -DGVPRINTNUM_TEST gvprintnum.c -o gvprintnum + */ + +#include +#include +#include + +#define DECPLACES 2 +#define DECPLACES_SCALE 100 +#define MAXNUM 999999999999999.99 +static char *maxnegnumstr = "-999999999999999.99"; + +int gvprintnum (char *buf, double number) +{ + char tmpbuf[20]; + char *result = tmpbuf+20; + long int N; + bool showzeros, negative; + int digit, i; + + /* + number limited to a working range: -MAXNUM >= n >= MAXNUM + N = number * DECPLACES_SCALE rounded towards zero, + printing to buffer in reverse direction, + printing "." after DECPLACES + suppressing trailing "0" and "." + */ + + if (number < -MAXNUM) { /* -ve limit */ + result = maxnegnumstr; + goto fin; + } + if (number > MAXNUM) { /* +ve limit */ + result = maxnegnumstr+1; /* +1 to skip the '-' sign */ + goto fin; + } + number *= DECPLACES_SCALE; /* scale by DECPLACES_SCALE */ + if (number < 0.0) /* round towards zero */ + N = number - 0.5; + else + N = number + 0.5; + if (N == 0) { /* special case for exactly 0 */ + result = "0"; + goto fin; + } + if ((negative = (N < 0))) /* avoid "-0" by testing rounded int */ + N = -N; /* make number +ve */ + *--result = '\0'; /* terminate the result string */ + showzeros = false; /* don't print trailing zeros */ + for (i = DECPLACES; N || i > 0; i--) { /* non zero remainder, + or still in fractional part */ + digit = N % 10; /* next least-significant digit */ + N /= 10; + if (digit || showzeros) { /* if digit is non-zero, + or if we are printing zeros */ + *--result = digit | '0'; /* convert digit to ascii */ + showzeros = true; /* from now on we must print zeros */ + } + if (i == 1) { /* if completed fractional part */ + if (showzeros) /* if there was a non-zero fraction */ + *--result = '.'; /* print decimal point */ + showzeros = true; /* print all digits in int part */ + } + } + if (negative) /* print "-" if needed */ + *--result = '-'; +fin: + strcpy(buf,result); /* copy result to user's buffer */ + return (strlen(result)); +} + + +#ifdef GVPRINTNUM_TEST +int main (int argc, char *argv[]) +{ + char buf[50]; + int len; + + double test[] = { + MAXNUM*1.1, MAXNUM*.9, + 1e8, 10.008, 10, 1, .1, .01, + .006, .005, .004, .001, 1e-8, + 0, -0, + -1e-8, -.001, -.004, -.005, -.006, + -.01, -.1, -1, -10, -10.008, -1e8, + -MAXNUM*.9, -MAXNUM*1.1 + }; + int i = sizeof(test) / sizeof(test[0]); + + while (i--) { + len = gvprintnum(buf, test[i]); + fprintf (stdout, "%g = %s\n", test[i], buf); + } + + return 0; +} +#endif