Mercurial > hg > octave-lyh
comparison liboctave/Range.cc @ 3858:de05e6bdf897
[project @ 2001-11-08 19:34:22 by jwe]
author | jwe |
---|---|
date | Thu, 08 Nov 2001 19:34:23 +0000 |
parents | f751e43de300 |
children | 6e86256e9c54 |
comparison
equal
deleted
inserted
replaced
3857:f7c7ecb63a7e | 3858:de05e6bdf897 |
---|---|
240 } | 240 } |
241 | 241 |
242 int | 242 int |
243 Range::nelem_internal (void) const | 243 Range::nelem_internal (void) const |
244 { | 244 { |
245 double ct = 3.0 * DBL_EPSILON; | 245 int retval = -1; |
246 | 246 |
247 double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct); | 247 if (rng_inc == 0 |
248 | 248 || (rng_limit > rng_base && rng_inc < 0) |
249 int n_elt = (tmp > 0.0 ? static_cast<int> (tmp) : 0); | 249 || (rng_limit < rng_base && rng_inc > 0)) |
250 | 250 { |
251 // If the final element that we would compute for the range is equal | 251 retval = 0; |
252 // to the limit of the range, or is an adjacent floating point | 252 } |
253 // number, accept it. Otherwise, try a range with one fewer | 253 else |
254 // element. If that fails, try again with one more element. | 254 { |
255 // | 255 double ct = 3.0 * DBL_EPSILON; |
256 // I'm not sure this is very good, but it seems to work better than | 256 |
257 // just using tfloor as above. For example, without it, the | 257 double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct); |
258 // expression 1.8:0.05:1.9 fails to produce the expected result of | 258 |
259 // [1.8, 1.85, 1.9]. | 259 int n_elt = (tmp > 0.0 ? static_cast<int> (tmp) : 0); |
260 | 260 |
261 if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit)) | 261 // If the final element that we would compute for the range is |
262 { | 262 // equal to the limit of the range, or is an adjacent floating |
263 if (teq (rng_base + (n_elt - 2) * rng_inc, rng_limit)) | 263 // point number, accept it. Otherwise, try a range with one |
264 n_elt--; | 264 // fewer element. If that fails, try again with one more |
265 else if (teq (rng_base + n_elt * rng_inc, rng_limit)) | 265 // element. |
266 n_elt++; | 266 // |
267 } | 267 // I'm not sure this is very good, but it seems to work better than |
268 | 268 // just using tfloor as above. For example, without it, the |
269 return (n_elt >= INT_MAX - 1) ? -1 : n_elt; | 269 // expression 1.8:0.05:1.9 fails to produce the expected result of |
270 // [1.8, 1.85, 1.9]. | |
271 | |
272 if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit)) | |
273 { | |
274 if (teq (rng_base + (n_elt - 2) * rng_inc, rng_limit)) | |
275 n_elt--; | |
276 else if (teq (rng_base + n_elt * rng_inc, rng_limit)) | |
277 n_elt++; | |
278 } | |
279 | |
280 retval = (n_elt >= INT_MAX - 1) ? -1 : n_elt; | |
281 } | |
282 | |
283 return retval; | |
270 } | 284 } |
271 | 285 |
272 /* | 286 /* |
273 ;;; Local Variables: *** | 287 ;;; Local Variables: *** |
274 ;;; mode: C++ *** | 288 ;;; mode: C++ *** |