Changeset 14458


Ignore:
Timestamp:
12/07/16 13:36:27 (4 years ago)
Author:
pfleck
Message:

#2715 Use decimal instead of double for bin-ranges to avoid floating point inaccuracies.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableControl.cs

    r14457 r14458  
    542542
    543543      int bins = histogramRows.Max(r => r.VisualProperties.Bins);
    544       double minValue = histogramRows.Min(r => r.Values.Min());
    545       double maxValue = histogramRows.Max(r => r.Values.Max());
    546       double intervalWidth = (maxValue - minValue) / bins;
     544      decimal minValue = (decimal)histogramRows.Min(r => r.Values.Min());
     545      decimal maxValue = (decimal)histogramRows.Max(r => r.Values.Max());
     546      decimal intervalWidth = (maxValue - minValue) / bins;
    547547      if (intervalWidth < 0) return;
    548548      if (intervalWidth == 0) {
     
    552552
    553553      if (!histogramRows.Any(r => r.VisualProperties.ExactBins)) {
    554         intervalWidth = HumanRoundRange(intervalWidth);
     554        intervalWidth = (decimal)HumanRoundRange((double)intervalWidth);
    555555        minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
    556556        maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
    557557      }
    558558
    559       double intervalCenter = intervalWidth / 2;
    560 
    561       double min = 0.0, max = 0.0;
     559      decimal intervalCenter = intervalWidth / 2;
     560
     561      decimal min = 0.0m, max = 0.0m;
    562562      if (!Double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue) && !Content.VisualProperties.XAxisMinimumAuto)
    563         min = Content.VisualProperties.XAxisMinimumFixedValue;
     563        min = (decimal)Content.VisualProperties.XAxisMinimumFixedValue;
    564564      else min = minValue;
    565565      if (!Double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue) && !Content.VisualProperties.XAxisMaximumAuto)
    566         max = Content.VisualProperties.XAxisMaximumFixedValue;
     566        max = (decimal)Content.VisualProperties.XAxisMaximumFixedValue;
    567567      else max = maxValue + intervalWidth;
    568568
    569       double axisInterval = intervalWidth / row.VisualProperties.ScaleFactor;
     569      double axisInterval = (double)intervalWidth / row.VisualProperties.ScaleFactor;
    570570
    571571      var area = chart.ChartAreas[0];
     
    575575
    576576      // get the range or intervals which define the grouping of the frequency values
    577       var doubleRange = DoubleRange(min, max, intervalWidth).Skip(1).ToList();
     577      var range = Range(min, max, intervalWidth).Skip(1).ToList();
    578578
    579579      // aggregate the row values by unique key and frequency value
     
    585585
    586586      // ensure that each column is displayed completely on the chart by adding two dummy datapoints on the upper and lower range
    587       series.Points.Add(new DataPoint(min - intervalWidth, 0));
    588       series.Points.Add(new DataPoint(max + intervalWidth, 0));
     587      series.Points.Add(new DataPoint((double)(min - intervalWidth), 0));
     588      series.Points.Add(new DataPoint((double)(max + intervalWidth), 0));
    589589
    590590      // add data points
    591591      int j = 0;
    592       foreach (var d in doubleRange) {
     592      foreach (var d in range) {
    593593        double sum = 0.0;
    594594        // sum the frequency values that fall within the same interval
    595         while (j < valueFrequencies.Count && valueFrequencies[j].Item1 < d) {
     595        while (j < valueFrequencies.Count && (decimal)valueFrequencies[j].Item1 < d) {
    596596          sum += valueFrequencies[j].Item2;
    597597          ++j;
     
    603603                              ? "Y"
    604604                              : Content.VisualProperties.YAxisTitle;
    605         series.Points.Add(new DataPoint(d - intervalCenter, sum) {
     605        series.Points.Add(new DataPoint((double)(d - intervalCenter), sum) {
    606606          ToolTip =
    607607            xAxisTitle + ": [" + (d - intervalWidth) + "-" + d + ")" + Environment.NewLine +
     
    612612
    613613    #region Helpers
    614     public static IEnumerable<double> DoubleRange(double min, double max, double step) {
    615       double i;
     614    public static IEnumerable<decimal> Range(decimal min, decimal max, decimal step) {
     615      decimal i;
    616616      for (i = min; i <= max; i += step)
    617617        yield return i;
Note: See TracChangeset for help on using the changeset viewer.