]> granicus.if.org Git - graphviz/commitdiff
new function: int gvprintnum(char *buf, double num);
authorellson <devnull@localhost>
Wed, 19 Dec 2007 19:20:50 +0000 (19:20 +0000)
committerellson <devnull@localhost>
Wed, 19 Dec 2007 19:20:50 +0000 (19:20 +0000)
   prints doubles as: fixed point, 2 decimal places, trailing zeroes suppressed

lib/gvc/gvprintnum.c [new file with mode: 0644]

diff --git a/lib/gvc/gvprintnum.c b/lib/gvc/gvprintnum.c
new file mode 100644 (file)
index 0000000..3a3c7a7
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#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