Avoid floating point precision problems in chart scale 20120324030503/pspp
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 24 Mar 2012 09:10:19 +0000 (10:10 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 24 Mar 2012 09:10:19 +0000 (10:10 +0100)
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.

src/output/cairo-chart.c

index 070319a58ed07ae78c40c896bea092f2ff4b58e1..5ab22af1c6ded452a22c599ed35982ac1d393889 100644 (file)
@@ -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