我的算术表达式编译器,如果在现代浏览器中运行,可以同时针对 FlatAssembler 和 GNU Assembler。 GNU 汇编器不支持以十进制表示法指定浮点值,因此我的编译器必须使用此函数将它们转换为位表示形式:
getIEEE754 = function (decimalNumber) {
var floatArray = new Float32Array([decimalNumber]);
var buffer = floatArray.buffer;
var intArray = new Int32Array(buffer);
return (
(highlight ? '<span style="color:#007700">' : "") +
"0x" +
intArray[0].toString(16) +
(highlight ? "<\/span>" : "")
);
};
但是,由于 Internet Explorer 6 不支持
Float32Array
和 Int32Array
,因此该功能在其中不起作用。因此,当在 Internet Explorer 6 中运行时,我的 Web 应用程序只能针对 Flat Assembler,它支持将小数解析为 IEEE754 浮点数。
那么,如果我的 Web 应用程序在 Internet Explorer 6 中运行,我怎样才能使其能够以 GNU Assembler 为目标呢?
您始终可以手动构建位表示,使用对数来估计指数,然后将该数字乘以适当的 2 次方以提取尾数位。像这样的东西:
function f32_to_u32(x) {
if (x !== x) /* NaN */
return 0x7fc00000;
var signBit = x + (1 / x) < 0 ? 0x80000000 : 0;
x = Math.abs(x);
// use the logarithm to estimate the exponent part,
// then refine the estimate to correct rounding errors
var exp = Math.floor(Math.log(x) * Math.LOG2E);
var mantd = x * Math.pow(2, 53 - exp);
if (mantd !== Math.floor(mantd))
exp++;
if (mantd < Math.pow(2, 53))
exp--;
// round and extract the mantissa
var mant;
if (exp >= 128) { /* infinities */
return (signBit | 0x7f800000) >>> 0;
} else if (exp <= -127) { /* denormals */
exp = -127;
mant = Math.round(x * Math.pow(2, 149)) & 0x7fffff;
} else {
mant = Math.round(x * Math.pow(2, 23 - exp)) & 0x7fffff;
}
exp = (exp + 127) << 23;
return (signBit | exp | mant) >>> 0;
}
我可以有把握地说这在 IE6 中有效,因为我在 IE5 中测试过它。