Mercurial > hg > octave-nkf
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 } |