Revision 1.166 by

Revision 1.167 by

… | … | ||
---|---|---|---|

40 | 40 | ||

41 | #ifndef ECB_H | 41 | #ifndef ECB_H |

42 | #define ECB_H | 42 | #define ECB_H |

43 | 43 | ||

44 | /* 16 bits major, 16 bits minor */ | 44 | /* 16 bits major, 16 bits minor */ |

45 | #define ECB_VERSION 0x00010004 | 45 | #define ECB_VERSION 0x00010005 |

46 | 46 | ||

47 | #ifdef _WIN32 | 47 | #ifdef _WIN32 |

48 | typedef signed char int8_t; | 48 | typedef signed char int8_t; |

49 | typedef unsigned char uint8_t; | 49 | typedef unsigned char uint8_t; |

50 | typedef signed short int16_t; | 50 | typedef signed short int16_t; |

… | … | ||

662 | } | 662 | } |

663 | #else | 663 | #else |

664 | #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) | 664 | #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) |

665 | #endif | 665 | #endif |

666 | 666 | ||

667 | ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint16_t x); | ||

668 | ecb_function_ ecb_const uint32_t | ||

669 | ecb_binary16_to_binary32 (uint16_t x) | ||

670 | { | ||

671 | unsigned int s = (x & 0x8000) << (31 - 15); | ||

672 | int e = (x >> 10) & 0x001f; | ||

673 | unsigned int m = x & 0x03ff; | ||

674 | |||

675 | if (ecb_expect_false (e == 31)) | ||

676 | /* infinity or NaN */ | ||

677 | e = 255 - (127 - 15); | ||

678 | else if (ecb_expect_false (!e)) | ||

679 | { | ||

680 | if (ecb_expect_true (!m)) | ||

681 | /* zero, handled by code below by forcing e to 0 */ | ||

682 | e = 0 - (127 - 15); | ||

683 | else | ||

684 | { | ||

685 | /* subnormal, renormalise */ | ||

686 | unsigned int s = 10 - ecb_ld32 (m); | ||

687 | |||

688 | m = (m << s) & 0x3ff; /* mask implicit bit */ | ||

689 | e -= s - 1; | ||

690 | } | ||

691 | } | ||

692 | |||

693 | /* e and m now are normalised, or zero, (or inf or nan) */ | ||

694 | e += 127 - 15; | ||

695 | |||

696 | return s | (e << 23) | (m << (23 - 10)); | ||

697 | } | ||

698 | |||

699 | ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x); | ||

700 | ecb_function_ ecb_const uint16_t | ||

701 | ecb_binary32_to_binary16 (uint32_t x) | ||

702 | { | ||

703 | unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */ | ||

704 | unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */ | ||

705 | unsigned int m = x & 0x007fffff; | ||

706 | |||

707 | x &= 0x7fffffff; | ||

708 | |||

709 | /* if it's within range of binary16 normals, use fast path */ | ||

710 | if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff)) | ||

711 | { | ||

712 | /* mantissa round-to-even */ | ||

713 | m += 0x00000fff + ((m >> (23 - 10)) & 1); | ||

714 | |||

715 | /* handle overflow */ | ||

716 | if (ecb_expect_false (m >= 0x00800000)) | ||

717 | { | ||

718 | m >>= 1; | ||

719 | e += 1; | ||

720 | } | ||

721 | |||

722 | return s | (e << 10) | (m >> (23 - 10)); | ||

723 | } | ||

724 | |||

725 | /* handle large numbers and infinity */ | ||

726 | if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000)) | ||

727 | return s | 0x7c00; | ||

728 | |||

729 | /* handle zero and subnormals */ | ||

730 | if (ecb_expect_true (x < 0x38800000)) | ||

731 | { | ||

732 | /* zero */ | ||

733 | if (ecb_expect_true (!x)) | ||

734 | return s; | ||

735 | |||

736 | /* handle subnormals */ | ||

737 | |||

738 | m |= 0x00800000; /* make implicit bit explicit */ | ||

739 | |||

740 | /* very tricky - we need to round to the nearest e (+10) bit value */ | ||

741 | { | ||

742 | unsigned int bits = 14 - e; | ||

743 | unsigned int half = (1 << (bits - 1)) - 1; | ||

744 | unsigned int even = (m >> bits) & 1; | ||

745 | |||

746 | /* if this overflows, we will end up with a normalised number */ | ||

747 | m = (m + half + even) >> bits; | ||

748 | } | ||

749 | |||

750 | return s | m; | ||

751 | } | ||

752 | |||

753 | /* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */ | ||

754 | m >>= 13; | ||

755 | |||

756 | return s | 0x7c00 | m | !m; | ||

757 | } | ||

758 | |||

667 | /*******************************************************************************/ | 759 | /*******************************************************************************/ |

668 | /* floating point stuff, can be disabled by defining ECB_NO_LIBM */ | 760 | /* floating point stuff, can be disabled by defining ECB_NO_LIBM */ |

669 | 761 | ||

670 | /* basically, everything uses "ieee pure-endian" floating point numbers */ | 762 | /* basically, everything uses "ieee pure-endian" floating point numbers */ |

671 | /* the only noteworthy exception is ancient armle, which uses order 43218765 */ | 763 | /* the only noteworthy exception is ancient armle, which uses order 43218765 */ |

… | … | ||

713 | #else | 805 | #else |

714 | #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e)) | 806 | #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e)) |

715 | #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) | 807 | #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) |

716 | #endif | 808 | #endif |

717 | 809 | ||

718 | /* converts an ieee half/binary16 to a float */ | ||

719 | ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); | ||

720 | ecb_function_ ecb_const float | ||

721 | ecb_binary16_to_float (uint16_t x) | ||

722 | { | ||

723 | int e = (x >> 10) & 0x1f; | ||

724 | int m = x & 0x3ff; | ||

725 | float r; | ||

726 | |||

727 | if (!e ) r = ecb_ldexpf (m , -24); | ||

728 | else if (e != 31) r = ecb_ldexpf (m + 0x400, e - 25); | ||

729 | else if (m ) r = ECB_NAN; | ||

730 | else r = ECB_INFINITY; | ||

731 | |||

732 | return x & 0x8000 ? -r : r; | ||

733 | } | ||

734 | |||

735 | /* convert a float to ieee single/binary32 */ | 810 | /* convert a float to ieee single/binary32 */ |

736 | ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); | 811 | ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); |

737 | ecb_function_ ecb_const uint32_t | 812 | ecb_function_ ecb_const uint32_t |

738 | ecb_float_to_binary32 (float x) | 813 | ecb_float_to_binary32 (float x) |

739 | { | 814 | { |

… | … | ||

870 | #endif | 945 | #endif |

871 | 946 | ||

872 | return r; | 947 | return r; |

873 | } | 948 | } |

874 | 949 | ||

875 | #endif | 950 | /* convert a float to ieee half/binary16 */ |

951 | ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x); | ||

952 | ecb_function_ ecb_const uint16_t | ||

953 | ecb_float_to_binary16 (float x) | ||

954 | { | ||

955 | return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x)); | ||

956 | } | ||

876 | 957 | ||

877 | #endif | 958 | /* convert an ieee half/binary16 to float */ |

959 | ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); | ||

960 | ecb_function_ ecb_const float | ||

961 | ecb_binary16_to_float (uint16_t x) | ||

962 | { | ||

963 | return ecb_binary32_to_float (ecb_binary16_to_binary32 (x)); | ||

964 | } | ||

878 | 965 | ||

966 | #endif | ||

967 | |||

968 | #endif | ||

969 |

– |
Removed lines |

+ |
Added lines |

< |
Changed lines |

> |
Changed lines |