summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorAdrián Medraño Calvo <adrian@medranocalvo.com>2018-07-13 11:24:32 (GMT)
committerAdrián Medraño Calvo <adrian@medranocalvo.com>2018-07-13 11:24:32 (GMT)
commitf4f7bb6aaad924ee83d7cc6b5b90c7c89083b698 (patch)
tree0697daecd7a74acd5cfc8da737177ee67d23154d /generic
parent061316ced72f9e6bc09e36e8fb42b41465e953ce (diff)
downloadblt-f4f7bb6aaad924ee83d7cc6b5b90c7c89083b698.zip
blt-f4f7bb6aaad924ee83d7cc6b5b90c7c89083b698.tar.gz
blt-f4f7bb6aaad924ee83d7cc6b5b90c7c89083b698.tar.bz2
Expand scale range to be at least DBL_EPSILON
A very small data range (from zero to a small floating point subnormal) caused nTicks to be excessively big, ending up in a request for a huge memory allocation for the axis. This commit limits the number of ticks and the scale range to values less than the floating point epsilon.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkbltGrAxis.C28
1 files changed, 20 insertions, 8 deletions
diff --git a/generic/tkbltGrAxis.C b/generic/tkbltGrAxis.C
index bac6316..8532600 100644
--- a/generic/tkbltGrAxis.C
+++ b/generic/tkbltGrAxis.C
@@ -819,18 +819,30 @@ void Axis::linearScale(double min, double max)
double range = max - min;
if (ops->reqStep > 0.0) {
step = ops->reqStep;
- while ((2 * step) >= range)
+ while ((2 * step) >= range && step >= (2 * DBL_EPSILON)) {
step *= 0.5;
- }
+ }
+ }
else {
range = niceNum(range, 0);
step = niceNum(range / ops->reqNumMajorTicks, 1);
}
-
- axisMin = tickMin = floor(min / step) * step + 0.0;
- axisMax = tickMax = ceil(max / step) * step + 0.0;
-
- nTicks = (int)((tickMax-tickMin) / step) + 1;
+ if (step >= DBL_EPSILON) {
+ axisMin = tickMin = floor(min / step) * step + 0.0;
+ axisMax = tickMax = ceil(max / step) * step + 0.0;
+ nTicks = (int)((tickMax-tickMin) / step) + 1;
+ } else {
+ /*
+ * A zero step can result from having a too small range, such that
+ * the floating point can no longer represent fractions of it (think
+ * subnormals). In such a case, let's just have two steps: the
+ * minimum and the maximum.
+ */
+ axisMin = tickMin = min;
+ axisMax = tickMax = min + DBL_EPSILON;
+ step = DBL_EPSILON;
+ nTicks = 2;
+ }
}
majorSweep_.step = step;
majorSweep_.initial = tickMin;
@@ -870,7 +882,7 @@ void Axis::setRange(AxisRange *rangePtr, double min, double max)
rangePtr->max = max;
rangePtr->range = max - min;
if (fabs(rangePtr->range) < DBL_EPSILON) {
- rangePtr->range = 1.0;
+ rangePtr->range = DBL_EPSILON;
}
rangePtr->scale = 1.0 / rangePtr->range;
}