| 2 | |
| 3 | |
| 4 | unsigned short cpu_float2half(float f) |
| 5 | { |
| 6 | unsigned short ret; |
| 7 | |
| 8 | unsigned x = *((int*)(void*)(&f)); |
| 9 | unsigned u = (x & 0x7fffffff), remainder, shift, lsb, lsb_s1, lsb_m1; |
| 10 | unsigned sign, exponent, mantissa; |
| 11 | |
| 12 | // Get rid of +NaN/-NaN case first. |
| 13 | if (u > 0x7f800000) { |
| 14 | ret = 0x7fffU; |
| 15 | return ret; |
| 16 | } |
| 17 | |
| 18 | sign = ((x >> 16) & 0x8000); |
| 19 | |
| 20 | // Get rid of +Inf/-Inf, +0/-0. |
| 21 | if (u > 0x477fefff) { |
| 22 | ret = sign | 0x7c00U; |
| 23 | return ret; |
| 24 | } |
| 25 | if (u < 0x33000001) { |
| 26 | ret = (sign | 0x0000); |
| 27 | return ret; |
| 28 | } |
| 29 | |
| 30 | exponent = ((u >> 23) & 0xff); |
| 31 | mantissa = (u & 0x7fffff); |
| 32 | |
| 33 | if (exponent > 0x70) { |
| 34 | shift = 13; |
| 35 | exponent -= 0x70; |
| 36 | } else { |
| 37 | shift = 0x7e - exponent; |
| 38 | exponent = 0; |
| 39 | mantissa |= 0x800000; |
| 40 | } |
| 41 | lsb = (1 << shift); |
| 42 | lsb_s1 = (lsb >> 1); |
| 43 | lsb_m1 = (lsb - 1); |
| 44 | |
| 45 | // Round to nearest even. |
| 46 | remainder = (mantissa & lsb_m1); |
| 47 | mantissa >>= shift; |
| 48 | if (remainder > lsb_s1 || (remainder == lsb_s1 && (mantissa & 0x1))) { |
| 49 | ++mantissa; |
| 50 | if (!(mantissa & 0x3ff)) { |
| 51 | ++exponent; |
| 52 | mantissa = 0; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | ret = (sign | (exponent << 10) | mantissa); |
| 57 | |
| 58 | return ret; |
| 59 | } |
| 60 | |
| 61 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { |