help-octave
[Top][All Lists]
Advanced

[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
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]