[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Unidentified subject!
From: |
John W. Eaton |
Subject: |
Re: Unidentified subject! |
Date: |
Wed, 13 Dec 2000 21:00:11 -0600 |
On 13-Dec-2000, Etienne Grossmann <address@hidden> wrote:
| I applied last Saturday's patch to 2.1.31, and I get :
|
| octave:25> 1:3:3
| ans =
|
| 1 4
|
|
| Is that expected?
No! Now I am doubly embarrassed. Here is an additional change that I
hope will make things work better. I'm still not entirely satisfied
with it, but at least it doesn't fail in such obviously horrible
ways. If you find problems with it, please let me know.
Thanks,
jwe
2000-12-13 John W. Eaton <address@hidden>
(Range::nelem_internal): Call tfloor, not round, but then try
harder to compute correct number of elements.
Index: Range.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/liboctave/Range.cc,v
retrieving revision 1.25
diff -u -r1.25 Range.cc
--- Range.cc 2000/12/10 06:03:06 1.25
+++ Range.cc 2000/12/14 02:54:35
@@ -230,14 +230,41 @@
return tfloor (x+0.5, ct);
}
+static inline bool
+teq (double u, double v, double ct = 3.0 * DBL_EPSILON)
+{
+ double tu = fabs (u);
+ double tv = fabs (v);
+
+ return fabs (u - v) < ((tu > tv ? tu : tv) * ct);
+}
+
int
Range::nelem_internal (void) const
{
double ct = 3.0 * DBL_EPSILON;
- double tmp = round ((rng_limit - rng_base + rng_inc) / rng_inc, ct);
+ double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct);
int n_elt = (tmp > 0.0 ? static_cast<int> (tmp) : 0);
+
+ // If the final element that we would compute for the range is equal
+ // to the limit of the range, or is an adjacent floating point
+ // number, accept it. Otherwise, try a range with one fewer
+ // element. If that fails, try again with one more element.
+ //
+ // I'm not sure this is very good, but it seems to work better than
+ // just using tfloor as above. For example, without it, the
+ // expression 1.8:0.05:1.9 fails to produce the expected result of
+ // [1.8, 1.85, 1.9].
+
+ if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit))
+ {
+ if (teq (rng_base + (n_elt - 2) * rng_inc, rng_limit))
+ n_elt--;
+ else if (teq (rng_base + n_elt * rng_inc, rng_limit))
+ n_elt++;
+ }
return (n_elt >= INT_MAX - 1) ? -1 : n_elt;
}
-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.
Octave's home on the web: http://www.octave.org
How to fund new projects: http://www.octave.org/funding.html
Subscription information: http://www.octave.org/archive.html
-------------------------------------------------------------