4

My Arithmetic Expression Compiler, if run in a modern browser, can target both FlatAssembler and GNU Assembler. GNU Assembler doesn't support specifying float values in decimal notation, so my compiler has to convert them into the bit representation using this function:

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>" : "")
  );
};

However, as Internet Explorer 6 doesn't support Float32Array and Int32Array, that function doesn't work in it. As such, when run in Internet Explorer 6, my web-app can only target Flat Assembler, which supports parsing decimal fractions into IEEE754 floats.

So, how can I make my web-app able to target GNU Assembler if it is being run in Internet Explorer 6?

2
  • Have you looked into typed array polyfills? Commented May 1, 2024 at 12:49
  • 3
    I hope you charge extra for IE6 support. Commented May 1, 2024 at 12:49

1 Answer 1

1

You can always construct the bit representation manually, using the logarithm to estimate the exponent, then multiplying the number by an appropriate power of two to extract the mantissa bits. Something like this:

// use exponentiation by squaring to avoid precision issues
// when Math.pow(base, n) is defined as Math.exp(n * Math.log(base))
function powi(base, n) {
  if (n < 0)
    return 1 / powi(base, -n);
  if (n === 0)
    return 1;
  if (n % 2 === 0)
    return powi(base * base, n / 2);
  return base * powi(base * base, (n - 1) / 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 * powi(2, 53 - exp);
  if (mantd !== Math.floor(mantd))
    exp++;
  if (mantd < /* 2⁵³ */ 0x20000000000000)
    exp--;

  // round to 32-bit precision 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 * powi(2, 149)) & 0x7fffff;
  } else {
    mant = Math.round(x * powi(2, 23 - exp)) & 0x7fffff;
  }
  exp = (exp + 127) << 23;

  return (signBit | exp | mant) >>> 0;
}

I can safely say this works in IE6, because I tested it in IE5.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.