1 /*------------------------------------------------------------------------- 2 * drawElements Base Portability Library 3 * ------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief 16-bit floating-point math. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deFloat16.h" 25 26 DE_BEGIN_EXTERN_C 27 deFloat32To16(float val32)28deFloat16 deFloat32To16 (float val32) 29 { 30 int sign; 31 int expotent; 32 int mantissa; 33 union 34 { 35 float f; 36 int i; 37 } x; 38 39 x.f = val32; 40 sign = (x.i >> 16) & 0x00008000; 41 expotent = ((x.i >> 23) & 0x000000ff) - (127 - 15); 42 mantissa = x.i & 0x007fffff; 43 44 if (expotent <= 0) 45 { 46 if (expotent < -10) 47 { 48 /* Rounds to zero. */ 49 return (deFloat16) sign; 50 } 51 52 /* Converted to denormalized half, add leading 1 to significand. */ 53 mantissa = mantissa | 0x00800000; 54 55 /* Round mantissa to nearest (10+e) */ 56 { 57 int t = 14 - expotent; 58 int a = (1 << (t - 1)) - 1; 59 int b = (mantissa >> t) & 1; 60 61 mantissa = (mantissa + a + b) >> t; 62 } 63 64 return (deFloat16) (sign | mantissa); 65 } 66 else if (expotent == 0xff - (127 - 15)) 67 { 68 if (mantissa == 0) 69 { 70 /* InF */ 71 return (deFloat16) (sign | 0x7c00); 72 } 73 else 74 { 75 /* NaN */ 76 mantissa >>= 13; 77 return (deFloat16) (sign | 0x7c00 | mantissa | (mantissa == 0)); 78 } 79 } 80 else 81 { 82 /* Normalized float. */ 83 mantissa = mantissa + 0x00000fff + ((mantissa >> 13) & 1); 84 85 if (mantissa & 0x00800000) 86 { 87 /* Overflow in mantissa. */ 88 mantissa = 0; 89 expotent += 1; 90 } 91 92 if (expotent > 30) 93 { 94 /* \todo [pyry] Cause hw fp overflow */ 95 return (deFloat16) (sign | 0x7c00); 96 } 97 98 return (deFloat16) (sign | (expotent << 10) | (mantissa >> 13)); 99 } 100 } 101 deFloat16To32(deFloat16 val16)102float deFloat16To32 (deFloat16 val16) 103 { 104 int sign; 105 int expotent; 106 int mantissa; 107 union 108 { 109 float f; 110 int i; 111 } x; 112 113 x.i = 0; 114 115 sign = ((int) val16 >> 15) & 0x00000001; 116 expotent = ((int) val16 >> 10) & 0x0000001f; 117 mantissa = (int) val16 & 0x000003ff; 118 119 if (expotent == 0) 120 { 121 if (mantissa == 0) 122 { 123 /* +/- 0 */ 124 x.i = sign << 31; 125 return x.f; 126 } 127 else 128 { 129 /* Denormalized, normalize it. */ 130 131 while (!(mantissa & 0x00000400)) 132 { 133 mantissa <<= 1; 134 expotent -= 1; 135 } 136 137 expotent += 1; 138 mantissa &= ~0x00000400; 139 } 140 } 141 else if (expotent == 31) 142 { 143 if (mantissa == 0) 144 { 145 /* +/- InF */ 146 x.i = (sign << 31) | 0x7f800000; 147 return x.f; 148 } 149 else 150 { 151 /* +/- NaN */ 152 x.i = (sign << 31) | 0x7f800000 | (mantissa << 13); 153 return x.f; 154 } 155 } 156 157 expotent = expotent + (127 - 15); 158 mantissa = mantissa << 13; 159 160 x.i = (sign << 31) | (expotent << 23) | mantissa; 161 return x.f; 162 } 163 164 DE_END_EXTERN_C 165