** Computes 'p' times 'x', where 'p' is a floating-point byte. Roughly, ** we have to multiply 'x' by the mantissa and then shift accordingly to ** the exponent. If the exponent is positive, both the multiplication ** and the shift increase 'x', so we have to care only about overflows. ** For negative exponents, however, multiplying before the shift keeps ** more significant bits, as long as the
| 97 | ** overflow, so we check which order is best. |
| 98 | */ |
| 99 | l_mem luaO_applyparam (lu_byte p, l_mem x) { |
| 100 | int m = p & 0xF; /* mantissa */ |
| 101 | int e = (p >> 4); /* exponent */ |
| 102 | if (e > 0) { /* normalized? */ |
| 103 | e--; /* correct exponent */ |
| 104 | m += 0x10; /* correct mantissa; maximum value is 0x1F */ |
| 105 | } |
| 106 | e -= 7; /* correct excess-7 */ |
| 107 | if (e >= 0) { |
| 108 | if (x < (MAX_LMEM / 0x1F) >> e) /* no overflow? */ |
| 109 | return (x * m) << e; /* order doesn't matter here */ |
| 110 | else /* real overflow */ |
| 111 | return MAX_LMEM; |
| 112 | } |
| 113 | else { /* negative exponent */ |
| 114 | e = -e; |
| 115 | if (x < MAX_LMEM / 0x1F) /* multiplication cannot overflow? */ |
| 116 | return (x * m) >> e; /* multiplying first gives more precision */ |
| 117 | else if ((x >> e) < MAX_LMEM / 0x1F) /* cannot overflow after shift? */ |
| 118 | return (x >> e) * m; |
| 119 | else /* real overflow */ |
| 120 | return MAX_LMEM; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | |
| 125 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, |