** 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
| 87 | ** overflow, so we check which order is best. |
| 88 | */ |
| 89 | l_mem luaO_applyparam (lu_byte p, l_mem x) { |
| 90 | int m = p & 0xF; /* mantissa */ |
| 91 | int e = (p >> 4); /* exponent */ |
| 92 | if (e > 0) { /* normalized? */ |
| 93 | e--; /* correct exponent */ |
| 94 | m += 0x10; /* correct mantissa; maximum value is 0x1F */ |
| 95 | } |
| 96 | e -= 7; /* correct excess-7 */ |
| 97 | if (e >= 0) { |
| 98 | if (x < (MAX_LMEM / 0x1F) >> e) /* no overflow? */ |
| 99 | return (x * m) << e; /* order doesn't matter here */ |
| 100 | else /* real overflow */ |
| 101 | return MAX_LMEM; |
| 102 | } |
| 103 | else { /* negative exponent */ |
| 104 | e = -e; |
| 105 | if (x < MAX_LMEM / 0x1F) /* multiplication cannot overflow? */ |
| 106 | return (x * m) >> e; /* multiplying first gives more precision */ |
| 107 | else if ((x >> e) < MAX_LMEM / 0x1F) /* cannot overflow after shift? */ |
| 108 | return (x >> e) * m; |
| 109 | else /* real overflow */ |
| 110 | return MAX_LMEM; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | |
| 115 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, |