Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decompressing Half Precision Floats in Javascript

I'm trying to read a binary file with javascript that contains a lot of 16-bit floating point numbers. Fairly certain it's IEEE standard, little endian. It's pretty straightforward to read the two bytes into an int, but from there I'm not having much success expanding that out into a full floating point number. Any clues?

like image 612
Toji Avatar asked Dec 12 '22 14:12

Toji


1 Answers

@Toji: Thanks a lot! Here a version with optimizations for NON high-end-engines like V8

var pow = Math.pow;
function decodeFloat16 (binary) {"use strict";
    var exponent = (binary & 0x7C00) >> 10,
        fraction = binary & 0x03FF;
    return (binary >> 15 ? -1 : 1) * (
        exponent ?
        (
            exponent === 0x1F ?
            fraction ? NaN : Infinity :
            pow(2, exponent - 15) * (1 + fraction / 0x400)
        ) :
        6.103515625e-5 * (fraction / 0x400)
    );
};

And a more complete IEEE 754 test:

function test() {
    var samples = [
        0x3C00, // = 1
            0xC000, // = −2
            0x7BFF, // = 6.5504 × 10^4 (max half precision)
            0x0400, // = 2^−14 ≈ 6.10352 × 10^−5 (minimum positive normal)
            0x0001, // = 2^−24 ≈ 5.96046 × 10^−8 (minimum strictly positive subnormal)
            0x0000, // = 0
            0x8000, // = −0
            0x7C00, // = Infinity
            0xFC00, // = −Infinity
            0x3555, // ≈ 0.33325... ≈ 1/3
            0x7C01  // = NaN
        ],
        i = samples.length;
    while (i--) samples[i] = decodeFloat16(samples[i]);
    return samples.join("\n");
};

Performance test results compared with the original code from Toji:

  • Chrome 17: +30 %
  • Safari 5.1: -10 % (don't ask me why)
  • Firefox 9: +11 %
  • IExplorer 9: +22 %
  • IExplorer 7: +14 %
like image 178
Thomas Fischer Avatar answered Dec 29 '22 09:12

Thomas Fischer