Mercurial > octave
comparison liboctave/numeric/lo-mappers.h @ 18869:23681c9ea7ba stable
better guess if rem or mod could be zero (bug #42627)
* lo-mappers.h (xmod, xrem): Don't treat abs(x)<=1 specially.
Return 0 if x/y is assumed an integer.
* data.cc: New tests for rem and mod.
author | Olaf Till <i7tiol@t-online.de> |
---|---|
date | Fri, 27 Jun 2014 11:49:22 +0200 |
parents | ebb3ef964372 |
children | 5b263e517c95 |
comparison
equal
deleted
inserted
replaced
18863:c457a84bc7d3 | 18869:23681c9ea7ba |
---|---|
319 retval = x; | 319 retval = x; |
320 else | 320 else |
321 { | 321 { |
322 T q = x / y; | 322 T q = x / y; |
323 | 323 |
324 T n = xfloor (q); | 324 if (X_NINT (y) != y |
325 | 325 && (std::abs ((q - X_NINT (q)) / X_NINT (q)) |
326 if (X_NINT (y) != y) | 326 < std::numeric_limits<T>::epsilon ())) |
327 retval = 0; | |
328 else | |
327 { | 329 { |
328 if (X_NINT (q) == q) | 330 T n = xfloor (q); |
329 n = q; | 331 |
330 else | 332 // Prevent use of extra precision. |
331 { | 333 volatile T tmp = y * n; |
332 if (x >= -1 && x <= 1) | 334 |
333 { | 335 retval = x - tmp; |
334 if (std::abs (q - X_NINT (q)) | |
335 < std::numeric_limits<T>::epsilon ()) | |
336 n = X_NINT (q); | |
337 } | |
338 else | |
339 { | |
340 if (std::abs ((q - X_NINT (q))/ X_NINT (q)) | |
341 < std::numeric_limits<T>::epsilon ()) | |
342 n = X_NINT (q); | |
343 } | |
344 } | |
345 } | 336 } |
346 | |
347 // Prevent use of extra precision. | |
348 volatile T tmp = y * n; | |
349 | |
350 retval = x - tmp; | |
351 } | 337 } |
352 | 338 |
353 if (x != y && y != 0 && retval != 0) | 339 if (x != y && y != 0 && retval != 0) |
354 retval = xcopysign (retval, y); | 340 retval = xcopysign (retval, y); |
355 | 341 |
366 retval = x; | 352 retval = x; |
367 else | 353 else |
368 { | 354 { |
369 T q = x / y; | 355 T q = x / y; |
370 | 356 |
371 T n = xtrunc (q); | 357 if (X_NINT (y) != y |
372 | 358 && (std::abs ((q - X_NINT (q)) / X_NINT (q)) |
373 if (X_NINT (y) != y) | 359 < std::numeric_limits<T>::epsilon ())) |
360 retval = 0; | |
361 else | |
374 { | 362 { |
375 if (X_NINT (q) == q) | 363 T n = xtrunc (q); |
376 n = q; | 364 |
377 else | 365 // Prevent use of extra precision. |
378 { | 366 volatile T tmp = y * n; |
379 if (x >= -1 && x <= 1) | 367 |
380 { | 368 retval = x - tmp; |
381 if (std::abs (q - X_NINT (q)) | |
382 < std::numeric_limits<T>::epsilon ()) | |
383 n = X_NINT (q); | |
384 } | |
385 else | |
386 { | |
387 if (std::abs ((q - X_NINT (q))/ X_NINT (q)) | |
388 < std::numeric_limits<T>::epsilon ()) | |
389 n = X_NINT (q); | |
390 } | |
391 } | |
392 } | 369 } |
393 | |
394 // Prevent use of extra precision. | |
395 volatile T tmp = y * n; | |
396 | |
397 retval = x - tmp; | |
398 } | 370 } |
399 | 371 |
400 if (x != y && y != 0 && retval != 0) | 372 if (x != y && y != 0 && retval != 0) |
401 retval = xcopysign (retval, x); | 373 retval = xcopysign (retval, x); |
402 | 374 |