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