… | |
… | |
553 | ecb_inline ecb_bool ecb_float_ieee (void) { return 0; } |
553 | ecb_inline ecb_bool ecb_float_ieee (void) { return 0; } |
554 | ecb_inline ecb_bool ecb_double_ieee (void) ecb_const; |
554 | ecb_inline ecb_bool ecb_double_ieee (void) ecb_const; |
555 | ecb_inline ecb_bool ecb_double_ieee (void) { return 0; } |
555 | ecb_inline ecb_bool ecb_double_ieee (void) { return 0; } |
556 | #endif |
556 | #endif |
557 | |
557 | |
|
|
558 | /*******************************************************************************/ |
|
|
559 | /* floating point stuff, can be disabled by defining ECB_NO_FP */ |
|
|
560 | |
|
|
561 | #ifndef ECB_NO_FP |
|
|
562 | |
|
|
563 | /* basically, everything uses "ieee pure-endian" floating point numbers */ |
|
|
564 | /* the only noteworthy exception is ancient armle, which uses order 43218765 */ |
|
|
565 | #if 0 \ |
|
|
566 | || __i386 || __i386__ \ |
|
|
567 | || __amd64 || __amd64__ || __x86_64 || __x86_64__ \ |
|
|
568 | || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \ |
|
|
569 | || defined __arm__ && defined __ARM_EABI__ \ |
|
|
570 | || defined __s390__ || defined __s390x__ \ |
|
|
571 | || defined __mips__ \ |
|
|
572 | || defined __alpha__ \ |
|
|
573 | || defined __hppa__ \ |
|
|
574 | || defined __ia64__ \ |
|
|
575 | || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64 |
|
|
576 | #define ECB_STDFP 1 |
|
|
577 | #else |
|
|
578 | #define ECB_STDFP 0 |
|
|
579 | #endif |
|
|
580 | |
558 | // convert a float to ieee single/binary32 |
581 | // convert a float to ieee single/binary32 |
559 | ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const; |
582 | ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const; |
560 | ecb_function_ uint32_t |
583 | ecb_function_ uint32_t |
561 | ecb_float_to_binary32 (float x) |
584 | ecb_float_to_binary32 (float x) |
562 | { |
585 | { |
|
|
586 | uint32_t r; |
|
|
587 | |
|
|
588 | #if ECB_STDFP |
|
|
589 | ((char *)&r) [0] = ((char *)&x)[0]; |
|
|
590 | ((char *)&r) [1] = ((char *)&x)[1]; |
|
|
591 | ((char *)&r) [2] = ((char *)&x)[2]; |
|
|
592 | ((char *)&r) [3] = ((char *)&x)[3]; |
|
|
593 | #else |
563 | /* slow emulation, works for anything but nan's and -0 */ |
594 | /* slow emulation, works for anything but nan's and -0 */ |
564 | ECB_EXTERN_C float frexpf (float v, int *e); |
595 | ECB_EXTERN_C float frexpf (float v, int *e); |
565 | uint32_t r, m; |
596 | uint32_t m; |
566 | int e; |
597 | int e; |
567 | |
598 | |
568 | if (x == 0e0f ) return 0; |
599 | if (x == 0e0f ) return 0; |
569 | if (x > +3.40282346638528860e+38f) return 0x7f800000U; |
600 | if (x > +3.40282346638528860e+38f) return 0x7f800000U; |
570 | if (x < -3.40282346638528860e+38f) return 0xff800000U; |
601 | if (x < -3.40282346638528860e+38f) return 0xff800000U; |
571 | |
602 | |
572 | m = frexpf (x, &e) * 0x1000000U; |
603 | m = frexpf (x, &e) * 0x1000000U; |
573 | |
604 | |
574 | r = m & 0x80000000U; |
605 | r = m & 0x80000000U; |
575 | |
606 | |
576 | if (r) |
607 | if (r) |
577 | m = -m; |
608 | m = -m; |
578 | |
609 | |
579 | if (e < -125) |
610 | if (e < -125) |
580 | { |
611 | { |
581 | m &= 0xffffffU; |
612 | m &= 0xffffffU; |
582 | m >>= (-125 - e); |
613 | m >>= (-125 - e); |
583 | e = -126; |
614 | e = -126; |
584 | } |
615 | } |
585 | |
616 | |
586 | r |= (e + 126) << 23; |
617 | r |= (e + 126) << 23; |
587 | r |= m & 0x7fffffU; |
618 | r |= m & 0x7fffffU; |
|
|
619 | #endif |
588 | |
620 | |
589 | return r; |
621 | return r; |
590 | } |
622 | } |
591 | |
623 | |
592 | // converts a ieee single/binary32 to a float |
624 | // converts a ieee single/binary32 to a float |
593 | ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const; |
625 | ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const; |
594 | ecb_function_ float |
626 | ecb_function_ float |
595 | ecb_binary32_to_float (uint32_t x) |
627 | ecb_binary32_to_float (uint32_t x) |
596 | { |
628 | { |
|
|
629 | float r; |
|
|
630 | |
|
|
631 | #if ECB_STDFP |
|
|
632 | ((char *)&r) [0] = ((char *)&x)[0]; |
|
|
633 | ((char *)&r) [1] = ((char *)&x)[1]; |
|
|
634 | ((char *)&r) [2] = ((char *)&x)[2]; |
|
|
635 | ((char *)&r) [3] = ((char *)&x)[3]; |
|
|
636 | #else |
597 | /* emulation, only works for normals and subnormals and +0 */ |
637 | /* emulation, only works for normals and subnormals and +0 */ |
598 | ECB_EXTERN_C float ldexpf (float x, int e); |
638 | ECB_EXTERN_C float ldexpf (float x, int e); |
599 | |
639 | |
600 | int neg = x >> 31; |
640 | int neg = x >> 31; |
601 | int e = (x >> 23) & 0xffU; |
641 | int e = (x >> 23) & 0xffU; |
602 | float r; |
|
|
603 | |
642 | |
604 | x &= 0x7fffffU; |
643 | x &= 0x7fffffU; |
605 | |
644 | |
606 | if (e) |
645 | if (e) |
607 | x |= 0x800000U; |
646 | x |= 0x800000U; |
608 | |
647 | |
609 | /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ |
648 | /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ |
610 | r = ldexpf (x * (1.f / 0x1000000U), e - 126); |
649 | r = ldexpf (x * (1.f / 0x1000000U), e - 126); |
611 | |
650 | |
612 | return neg ? -r : r; |
651 | r = neg ? -r : r; |
613 | } |
652 | #endif |
614 | |
653 | |
|
|
654 | return r; |
|
|
655 | } |
|
|
656 | |
615 | ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const; |
657 | ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const; |
616 | ecb_function_ uint64_t |
658 | ecb_function_ uint64_t |
617 | ecb_double_to_binary64 (double x) |
659 | ecb_double_to_binary64 (double x) |
618 | { |
660 | { |
619 | } |
661 | } |
620 | |
662 | |
621 | #endif |
663 | #endif |
622 | |
664 | |
|
|
665 | #endif |
|
|
666 | |