From: John Darrington <john@darrington.wattle.id.au>
Date: Sat, 24 Mar 2012 09:10:19 +0000 (+0100)
Subject: Avoid floating point precision problems in chart scale
X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fbuilds%2F20120324030503%2Fpspp;p=pspp

Avoid floating point precision problems in chart scale

Some charts were being drawn with a tick mark at positions
close to but not exactly zero Eg: 2.187433298e-27
This change avoids this problem.
---

diff --git a/src/output/cairo-chart.c b/src/output/cairo-chart.c
index 070319a58e..5ab22af1c6 100644
--- a/src/output/cairo-chart.c
+++ b/src/output/cairo-chart.c
@@ -293,7 +293,7 @@ static void
 xrchart_write_scale (cairo_t *cr, struct xrchart_geometry *geom,
 		     double smin, double smax, int ticks, enum tick_orientation orient)
 {
-  double y;
+  int s;
 
   const double tick_interval =
     chart_rounded_tick ((smax - smin) / (double) ticks);
@@ -304,15 +304,14 @@ xrchart_write_scale (cairo_t *cr, struct xrchart_geometry *geom,
   geom->axis[orient].scale = (fabs (geom->axis[orient].data_max - geom->axis[orient].data_min)
      / fabs (geom->axis[orient].max - geom->axis[orient].min));
 
-  /*
-  geom->axis[orient].scale = (fabs (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min)
-     / fabs (geom->axis[orient].max - geom->axis[orient].min));
-  */
-
-
-  for (y = geom->axis[orient].min; y <= geom->axis[orient].max; y += tick_interval)
-    draw_tick (cr, geom, orient,
-	       (y - geom->axis[orient].min) * geom->axis[orient].scale, "%g", y);
+  for (s = 0 ; s < (geom->axis[orient].max - geom->axis[orient].min) / tick_interval; ++s)
+    {
+      double pos = s * tick_interval + geom->axis[orient].min; 
+      if (fabs (pos) < DBL_EPSILON)
+      	pos = 0;
+      draw_tick (cr, geom, orient,
+		 s * tick_interval * geom->axis[orient].scale, "%g", pos);
+    }
 }
 
 void