ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libecb/ecb.h
(Generate patch)

Comparing libecb/ecb.h (file contents):
Revision 1.103 by root, Thu Jun 28 18:04:44 2012 UTC vs.
Revision 1.104 by root, Thu Jun 28 19:38:29 2012 UTC

534 } 534 }
535#else 535#else
536 #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) 536 #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
537#endif 537#endif
538 538
539#if __STDC_IEC_559__
540 // we assume this is defined for most C and many C++ compilers
541 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
542 ecb_inline ecb_bool ecb_float_ieee (void) { return 1; }
543 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
544 ecb_inline ecb_bool ecb_double_ieee (void) { return 1; }
545#elif ECB_CPP
546 #include <limits>
547 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
548 ecb_inline ecb_bool ecb_float_ieee (void) { return std::numeric_limits<float >::is_iec559; }
549 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
550 ecb_inline ecb_bool ecb_double_ieee (void) { return std::numeric_limits<double>::is_iec559; }
551#else
552 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
553 ecb_inline ecb_bool ecb_float_ieee (void) { return 0; }
554 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
555 ecb_inline ecb_bool ecb_double_ieee (void) { return 0; }
556#endif
557
558/*******************************************************************************/ 539/*******************************************************************************/
559/* floating point stuff, can be disabled by defining ECB_NO_FP */ 540/* floating point stuff, can be disabled by defining ECB_NO_LIBM */
560 541
561#ifndef ECB_NO_FP
562
563 /* basically, everything uses "ieee pure-endian" floating point numbers */ 542/* basically, everything uses "ieee pure-endian" floating point numbers */
564 /* the only noteworthy exception is ancient armle, which uses order 43218765 */ 543/* the only noteworthy exception is ancient armle, which uses order 43218765 */
565 #if 0 \ 544#if 0 \
566 || __i386 || __i386__ \ 545 || __i386 || __i386__ \
567 || __amd64 || __amd64__ || __x86_64 || __x86_64__ \ 546 || __amd64 || __amd64__ || __x86_64 || __x86_64__ \
568 || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \ 547 || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
569 || defined __arm__ && defined __ARM_EABI__ \ 548 || defined __arm__ && defined __ARM_EABI__ \
570 || defined __s390__ || defined __s390x__ \ 549 || defined __s390__ || defined __s390x__ \
571 || defined __mips__ \ 550 || defined __mips__ \
572 || defined __alpha__ \ 551 || defined __alpha__ \
573 || defined __hppa__ \ 552 || defined __hppa__ \
574 || defined __ia64__ \ 553 || defined __ia64__ \
575 || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64 554 || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
576 #define ECB_STDFP 1 555 #define ECB_STDFP 1
556 #include <string.h> /* for memcpy */
557#else
558 #define ECB_STDFP 0
559#endif
560
561#ifndef ECB_NO_LIBM
562
563 #if __STDC_IEC_559__ || ECB_STDFP
564 /* we assume this is defined for most C and many C++ compilers */
565 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
566 ecb_inline ecb_bool ecb_float_ieee (void) { return 1; }
567 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
568 ecb_inline ecb_bool ecb_double_ieee (void) { return 1; }
569 #elif ECB_CPP
570 #include <limits>
571 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
572 ecb_inline ecb_bool ecb_float_ieee (void) { return std::numeric_limits<float >::is_iec559; }
573 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
574 ecb_inline ecb_bool ecb_double_ieee (void) { return std::numeric_limits<double>::is_iec559; }
577 #else 575 #else
578 #define ECB_STDFP 0 576 ecb_inline ecb_bool ecb_float_ieee (void) ecb_const;
577 ecb_inline ecb_bool ecb_float_ieee (void) { return 0; }
578 ecb_inline ecb_bool ecb_double_ieee (void) ecb_const;
579 ecb_inline ecb_bool ecb_double_ieee (void) { return 0; }
579 #endif 580 #endif
580 581
581 // convert a float to ieee single/binary32 582 /* convert a float to ieee single/binary32 */
582 ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const; 583 ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
583 ecb_function_ uint32_t 584 ecb_function_ uint32_t
584 ecb_float_to_binary32 (float x) 585 ecb_float_to_binary32 (float x)
585 { 586 {
586 uint32_t r; 587 uint32_t r;
587 588
588 #if ECB_STDFP 589 #if ECB_STDFP
589 ((char *)&r) [0] = ((char *)&x)[0]; 590 memcpy (&r, &x, 4);
590 ((char *)&r) [1] = ((char *)&x)[1];
591 ((char *)&r) [2] = ((char *)&x)[2];
592 ((char *)&r) [3] = ((char *)&x)[3];
593 #else 591 #else
594 /* slow emulation, works for anything but nan's and -0 */ 592 /* slow emulation, works for anything but nan's and -0 */
595 ECB_EXTERN_C float frexpf (float v, int *e); 593 ECB_EXTERN_C float frexpf (float v, int *e);
596 uint32_t m; 594 uint32_t m;
597 int e; 595 int e;
619 #endif 617 #endif
620 618
621 return r; 619 return r;
622 } 620 }
623 621
624 // converts a ieee single/binary32 to a float 622 /* converts an ieee single/binary32 to a float */
625 ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const; 623 ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const;
626 ecb_function_ float 624 ecb_function_ float
627 ecb_binary32_to_float (uint32_t x) 625 ecb_binary32_to_float (uint32_t x)
628 { 626 {
629 float r; 627 float r;
630 628
631 #if ECB_STDFP 629 #if ECB_STDFP
632 ((char *)&r) [0] = ((char *)&x)[0]; 630 memcpy (&r, &x, 4);
633 ((char *)&r) [1] = ((char *)&x)[1];
634 ((char *)&r) [2] = ((char *)&x)[2];
635 ((char *)&r) [3] = ((char *)&x)[3];
636 #else 631 #else
637 /* emulation, only works for normals and subnormals and +0 */ 632 /* emulation, only works for normals and subnormals and +0 */
638 ECB_EXTERN_C float ldexpf (float x, int e); 633 ECB_EXTERN_C float ldexpf (float x, int e);
639 634
640 int neg = x >> 31; 635 int neg = x >> 31;
642 637
643 x &= 0x7fffffU; 638 x &= 0x7fffffU;
644 639
645 if (e) 640 if (e)
646 x |= 0x800000U; 641 x |= 0x800000U;
642 else
643 e = 1;
647 644
648 /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ 645 /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
649 r = ldexpf (x * (1.f / 0x1000000U), e - 126); 646 r = ldexpf (x * (1.f / 0x1000000U), e - 126);
650 647
651 r = neg ? -r : r; 648 r = neg ? -r : r;
652 #endif 649 #endif
653 650
654 return r; 651 return r;
655 } 652 }
656 653
654 /* convert a double to ieee double/binary64 */
657 ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const; 655 ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const;
658 ecb_function_ uint64_t 656 ecb_function_ uint64_t
659 ecb_double_to_binary64 (double x) 657 ecb_double_to_binary64 (double x)
660 { 658 {
661 } 659 uint64_t r;
662 660
661 #if ECB_STDFP
662 memcpy (&r, &x, 8);
663 #else
664 /* slow emulation, works for anything but nan's and -0 */
665 ECB_EXTERN_C double frexp (double v, int *e);
666 uint64_t m;
667 int e;
668
669 if (x == 0e0 ) return 0;
670 if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U;
671 if (x < -1.79769313486231470e+308) return 0xfff0000000000000U;
672
673 m = frexpf (x, &e) * 0x1000000U;
674 m = frexp (x, &e) * 0x20000000000000U;
675
676 r = m & 0x8000000000000000;;
677
678 if (r)
679 m = -m;
680
681 if (e < -1021)
682 {
683 m &= 0x1fffffffffffffU;
684 m >>= (-1021 - e);
685 e = -1022;
686 }
687
688 r |= ((uint64_t)(e + 1022)) << 52;
689 r |= m & 0xfffffffffffffU;
663#endif 690 #endif
664 691
692 return r;
693 }
694
695 /* converts an ieee double/binary64 to a double */
696 ecb_function_ double ecb_binary64_to_double (uint64_t x) ecb_const;
697 ecb_function_ double
698 ecb_binary64_to_double (uint64_t x)
699 {
700 double r;
701
702 #if ECB_STDFP
703 memcpy (&r, &x, 8);
704 #else
705 /* emulation, only works for normals and subnormals and +0 */
706 ECB_EXTERN_C double ldexp (double x, int e);
707
708 int neg = x >> 63;
709 int e = (x >> 52) & 0x7ffU;
710
711 x &= 0xfffffffffffffU;
712
713 if (e)
714 x |= 0x10000000000000U;
715 else
716 e = 1;
717
718 /* we distrust ldexpf a bit and do the 2**-53 scaling by an extra multiply */
719 r = ldexp (x * (1. / 0x20000000000000U), e - 1022);
720
721 r = neg ? -r : r;
665#endif 722 #endif
666 723
724 return r;
725 }
726
727#endif
728
729#endif
730

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines