comparison liboctave/oct-inttypes.h @ 10405:cc69a17ec801

remove integer math warnings
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 09 Mar 2010 08:06:30 +0100
parents 65d5776379c3
children 00219bdd2d17
comparison
equal deleted inserted replaced
10404:b40a5fd3af41 10405:cc69a17ec801
244 244
245 // Efficiency of the following depends on inlining and dead code 245 // Efficiency of the following depends on inlining and dead code
246 // elimination, but that should be a piece of cake for most compilers. 246 // elimination, but that should be a piece of cake for most compilers.
247 if (chk_min::op (value, static_cast<S> (min_val ()))) 247 if (chk_min::op (value, static_cast<S> (min_val ())))
248 { 248 {
249 ftrunc = true;
250 return min_val (); 249 return min_val ();
251 } 250 }
252 else if (chk_max::op (value, static_cast<S> (max_val ()))) 251 else if (chk_max::op (value, static_cast<S> (max_val ())))
253 { 252 {
254 ftrunc = true;
255 return max_val (); 253 return max_val ();
256 } 254 }
257 else 255 else
258 return static_cast<T> (value); 256 return static_cast<T> (value);
259 } 257 }
282 // Compute proper thresholds. 280 // Compute proper thresholds.
283 static const S thmin = compute_threshold (static_cast<S> (min_val ()), min_val ()); 281 static const S thmin = compute_threshold (static_cast<S> (min_val ()), min_val ());
284 static const S thmax = compute_threshold (static_cast<S> (max_val ()), max_val ()); 282 static const S thmax = compute_threshold (static_cast<S> (max_val ()), max_val ());
285 if (xisnan (value)) 283 if (xisnan (value))
286 { 284 {
287 fnan = true;
288 return static_cast<T> (0); 285 return static_cast<T> (0);
289 } 286 }
290 else if (value < thmin) 287 else if (value < thmin)
291 { 288 {
292 ftrunc = true;
293 return min_val (); 289 return min_val ();
294 } 290 }
295 else if (value > thmax) 291 else if (value > thmax)
296 { 292 {
297 ftrunc = true;
298 return max_val (); 293 return max_val ();
299 } 294 }
300 else 295 else
301 { 296 {
302 S rvalue = xround (value); 297 S rvalue = xround (value);
303 if (rvalue != value) fnon_int = true;
304 return static_cast<T> (rvalue); 298 return static_cast<T> (rvalue);
305 } 299 }
306 } 300 }
307
308 // Exception flags rationale:
309 // There is little reason to distinguish math and conversion exceptions at
310 // octave_int level. Doing this would require special constructors for
311 // intermediate int results in math computations.
312 //
313 // Boolean flags are used rather than a single flag, because raising a boolean
314 // flag is faster than masking an int flag (single mov versus mov, or, mov).
315 // Also, it is atomic, and thus thread-safe (but there is *one* flag for all
316 // threads).
317
318 static bool get_trunc_flag () { return ftrunc; }
319 static bool get_nan_flag () { return fnan; }
320 static bool get_non_int_flag () { return fnon_int; }
321 static void clear_conv_flags ()
322 {
323 ftrunc = false;
324 fnan = false;
325 fnon_int = false;
326 }
327 // For compatibility.
328 static bool get_math_trunc_flag () { return ftrunc || fnan; }
329 static void clear_conv_flag () { clear_conv_flags (); }
330
331 protected:
332
333 // Conversion flags.
334 static bool ftrunc;
335 static bool fnon_int;
336 static bool fnan;
337 }; 301 };
338
339 template<class T> bool octave_int_base<T>::ftrunc = false;
340 template<class T> bool octave_int_base<T>::fnon_int = false;
341 template<class T> bool octave_int_base<T>::fnan = false;
342 302
343 // Saturated (homogeneous) integer arithmetics. The signed and unsigned 303 // Saturated (homogeneous) integer arithmetics. The signed and unsigned
344 // implementations are significantly different, so we implement another layer 304 // implementations are significantly different, so we implement another layer
345 // and completely specialize. Arithmetics inherits from octave_int_base so that 305 // and completely specialize. Arithmetics inherits from octave_int_base so that
346 // it can use its exceptions and truncation functions. 306 // it can use its exceptions and truncation functions.
368 328
369 static T 329 static T
370 lshift (T x, int n) { return x << n; } 330 lshift (T x, int n) { return x << n; }
371 331
372 static T 332 static T
373 minus (T x) 333 minus (T)
374 { 334 {
375 if (x != 0) octave_int_base<T>::ftrunc = true;
376 return static_cast<T> (0); 335 return static_cast<T> (0);
377 } 336 }
378 337
379 // the overflow behaviour for unsigned integers is guaranteed by C/C++, 338 // the overflow behaviour for unsigned integers is guaranteed by C/C++,
380 // so the following should always work. 339 // so the following should always work.
383 { 342 {
384 T u = x + y; 343 T u = x + y;
385 if (u < x) 344 if (u < x)
386 { 345 {
387 u = octave_int_base<T>::max_val (); 346 u = octave_int_base<T>::max_val ();
388 octave_int_base<T>::ftrunc = true;
389 } 347 }
390 return u; 348 return u;
391 } 349 }
392 350
393 static T 351 static T
395 { 353 {
396 T u = x - y; 354 T u = x - y;
397 if (u > x) 355 if (u > x)
398 { 356 {
399 u = 0; 357 u = 0;
400 octave_int_base<T>::ftrunc = true;
401 } 358 }
402 return u; 359 return u;
403 } 360 }
404 361
405 // Multiplication is done using promotion to wider integer type. If there is 362 // Multiplication is done using promotion to wider integer type. If there is
424 if (w >= y-w) z += 1; 381 if (w >= y-w) z += 1;
425 return z; 382 return z;
426 } 383 }
427 else 384 else
428 { 385 {
429 octave_int_base<T>::ftrunc = true;
430 return x ? octave_int_base<T>::max_val () : 0; 386 return x ? octave_int_base<T>::max_val () : 0;
431 } 387 }
432 } 388 }
433 }; 389 };
434 390
439 octave_int_arith_base<uint64_t, false>:: mul (uint64_t x, uint64_t y) 395 octave_int_arith_base<uint64_t, false>:: mul (uint64_t x, uint64_t y)
440 { 396 {
441 long double p = static_cast<long double> (x) * static_cast<long double> (y); 397 long double p = static_cast<long double> (x) * static_cast<long double> (y);
442 if (p > static_cast<long double> (octave_int_base<uint64_t>::max_val ())) 398 if (p > static_cast<long double> (octave_int_base<uint64_t>::max_val ()))
443 { 399 {
444 octave_int_base<uint64_t>::ftrunc = true;
445 return octave_int_base<uint64_t>::max_val (); 400 return octave_int_base<uint64_t>::max_val ();
446 } 401 }
447 else 402 else
448 return static_cast<uint64_t> (p); 403 return static_cast<uint64_t> (p);
449 } 404 }
502 T m = x >> std::numeric_limits<T>::digits; 457 T m = x >> std::numeric_limits<T>::digits;
503 T y = (x ^ m) - m; 458 T y = (x ^ m) - m;
504 if (y < 0) 459 if (y < 0)
505 { 460 {
506 y = octave_int_base<T>::max_val (); 461 y = octave_int_base<T>::max_val ();
507 octave_int_base<T>::ftrunc = true;
508 } 462 }
509 return y; 463 return y;
510 #else 464 #else
511 // -INT_MAX is safe because C++ actually allows only three implementations 465 // -INT_MAX is safe because C++ actually allows only three implementations
512 // of integers: sign & magnitude, ones complement and twos complement. 466 // of integers: sign & magnitude, ones complement and twos complement.
515 T y; 469 T y;
516 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val () 470 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
517 && x == octave_int_base<T>::min_val ()) 471 && x == octave_int_base<T>::min_val ())
518 { 472 {
519 y = octave_int_base<T>::max_val (); 473 y = octave_int_base<T>::max_val ();
520 octave_int_base<T>::ftrunc = true;
521 } 474 }
522 else 475 else
523 y = (x < 0) ? -x : x; 476 y = (x < 0) ? -x : x;
524 return y; 477 return y;
525 #endif 478 #endif
549 #ifdef HAVE_FAST_INT_OPS 502 #ifdef HAVE_FAST_INT_OPS
550 T y = -x; 503 T y = -x;
551 if (y == octave_int_base<T>::min_val ()) 504 if (y == octave_int_base<T>::min_val ())
552 { 505 {
553 --y; 506 --y;
554 octave_int_base<T>::ftrunc = false;
555 } 507 }
556 return y; 508 return y;
557 #else 509 #else
558 T y; 510 T y;
559 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val () 511 if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
560 && x == octave_int_base<T>::min_val ()) 512 && x == octave_int_base<T>::min_val ())
561 { 513 {
562 y = octave_int_base<T>::max_val (); 514 y = octave_int_base<T>::max_val ();
563 octave_int_base<T>::ftrunc = true;
564 } 515 }
565 else 516 else
566 y = -x; 517 y = -x;
567 return y; 518 return y;
568 #endif 519 #endif
578 T u = static_cast<UT> (x) + static_cast<UT> (y); 529 T u = static_cast<UT> (x) + static_cast<UT> (y);
579 T ux = u ^ x, uy = u ^ y; 530 T ux = u ^ x, uy = u ^ y;
580 if ((ux & uy) < 0) 531 if ((ux & uy) < 0)
581 { 532 {
582 u = octave_int_base<T>::max_val () + signbit (~u); 533 u = octave_int_base<T>::max_val () + signbit (~u);
583 octave_int_base<T>::ftrunc = true;
584 } 534 }
585 return u; 535 return u;
586 #else 536 #else
587 // We shall carefully avoid anything that may overflow. 537 // We shall carefully avoid anything that may overflow.
588 T u; 538 T u;
589 if (y < 0) 539 if (y < 0)
590 { 540 {
591 if (x < octave_int_base<T>::min_val () - y) 541 if (x < octave_int_base<T>::min_val () - y)
592 { 542 {
593 u = octave_int_base<T>::min_val (); 543 u = octave_int_base<T>::min_val ();
594 octave_int_base<T>::ftrunc = true;
595 } 544 }
596 else 545 else
597 u = x + y; 546 u = x + y;
598 } 547 }
599 else 548 else
600 { 549 {
601 if (x > octave_int_base<T>::max_val () - y) 550 if (x > octave_int_base<T>::max_val () - y)
602 { 551 {
603 u = octave_int_base<T>::max_val (); 552 u = octave_int_base<T>::max_val ();
604 octave_int_base<T>::ftrunc = true;
605 } 553 }
606 else 554 else
607 u = x + y; 555 u = x + y;
608 } 556 }
609 557
622 T u = static_cast<UT> (x) - static_cast<UT> (y); 570 T u = static_cast<UT> (x) - static_cast<UT> (y);
623 T ux = u ^ x, uy = u ^ ~y; 571 T ux = u ^ x, uy = u ^ ~y;
624 if ((ux & uy) < 0) 572 if ((ux & uy) < 0)
625 { 573 {
626 u = octave_int_base<T>::max_val () + signbit (~u); 574 u = octave_int_base<T>::max_val () + signbit (~u);
627 octave_int_base<T>::ftrunc = true;
628 } 575 }
629 return u; 576 return u;
630 #else 577 #else
631 // We shall carefully avoid anything that may overflow. 578 // We shall carefully avoid anything that may overflow.
632 T u; 579 T u;
633 if (y < 0) 580 if (y < 0)
634 { 581 {
635 if (x > octave_int_base<T>::max_val () + y) 582 if (x > octave_int_base<T>::max_val () + y)
636 { 583 {
637 u = octave_int_base<T>::max_val (); 584 u = octave_int_base<T>::max_val ();
638 octave_int_base<T>::ftrunc = true;
639 } 585 }
640 else 586 else
641 u = x - y; 587 u = x - y;
642 } 588 }
643 else 589 else
644 { 590 {
645 if (x < octave_int_base<T>::min_val () + y) 591 if (x < octave_int_base<T>::min_val () + y)
646 { 592 {
647 u = octave_int_base<T>::min_val (); 593 u = octave_int_base<T>::min_val ();
648 octave_int_base<T>::ftrunc = true;
649 } 594 }
650 else 595 else
651 u = x - y; 596 u = x - y;
652 } 597 }
653 598
671 div (T x, T y) 616 div (T x, T y)
672 { 617 {
673 T z; 618 T z;
674 if (y == 0) 619 if (y == 0)
675 { 620 {
676 octave_int_base<T>::ftrunc = true;
677 if (x < 0) 621 if (x < 0)
678 z = octave_int_base<T>::min_val (); 622 z = octave_int_base<T>::min_val ();
679 else if (x != 0) 623 else if (x != 0)
680 z = octave_int_base<T>::max_val (); 624 z = octave_int_base<T>::max_val ();
681 else 625 else
684 else if (y < 0) 628 else if (y < 0)
685 { 629 {
686 // This is a special case that overflows as well. 630 // This is a special case that overflows as well.
687 if (y == -1 && x == octave_int_base<T>::min_val ()) 631 if (y == -1 && x == octave_int_base<T>::min_val ())
688 { 632 {
689 octave_int_base<T>::ftrunc = true;
690 z = octave_int_base<T>::max_val (); 633 z = octave_int_base<T>::max_val ();
691 } 634 }
692 else 635 else
693 { 636 {
694 z = x / y; 637 z = x / y;
723 // NOTE: We could maybe do it with a single branch if HAVE_FAST_INT_OPS, but it 666 // NOTE: We could maybe do it with a single branch if HAVE_FAST_INT_OPS, but it
724 // would require one more runtime conversion, so the question is whether it would 667 // would require one more runtime conversion, so the question is whether it would
725 // really be faster. 668 // really be faster.
726 if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ())) 669 if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ()))
727 { 670 {
728 octave_int_base<int64_t>::ftrunc = true;
729 return octave_int_base<int64_t>::max_val (); 671 return octave_int_base<int64_t>::max_val ();
730 } 672 }
731 else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ())) 673 else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ()))
732 { 674 {
733 octave_int_base<int64_t>::ftrunc = true;
734 return octave_int_base<int64_t>::min_val (); 675 return octave_int_base<int64_t>::min_val ();
735 } 676 }
736 else 677 else
737 return static_cast<int64_t> (p); 678 return static_cast<int64_t> (p);
738 } 679 }