1

I want to read data from in an old file format. The format uses IBM floating point numbers, and I want to read it in a JavaScript program. IBM floating point representation was used on the IBM System/360.

How can I convert the IBM floating points to JavaScript numbers?

Hallgrim
  • 15,143
  • 10
  • 46
  • 54
  • I was not aware IBM had their own floating-point system. Are you referring to [this](http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture)? – Frédéric Hamidi Sep 25 '14 at 15:45
  • 2
    IBM had their own floating point representation back in the days. Before IEEE helped everyone agree on the representation that is mostly used today. – Hallgrim Sep 25 '14 at 16:38
  • Perhaps this is of some use (not in Javascript, but still): http://stackoverflow.com/questions/6399486/ibm-to-ieee-floating-point-conv – NPE Sep 25 '14 at 16:44
  • Rather than specifically thinking Javascript number, look for anything that converts IBM proprietary to IEEE 754 binary floating point, including the question @NPE linked. – Patricia Shanahan Sep 25 '14 at 16:48

2 Answers2

3

This function takes a buffer of little endian IBM floats and converts them to a number:

function ibm2js(buffer) {
    var sign = buffer[0] >> 7
    var exponent = buffer[0] & 0x7f
    var fraction = 0
    function bit(buffer, bit) {
        return buffer[Math.floor(bit / 8)] >> (7 - (bit % 8)) & 1
    }
    for (var i = 0; i < 24; i++) {
        fraction += bit(buffer, 8 + i) / (2 << i)
    }
    return (1 - 2 * sign) * Math.pow(16.0, exponent - 64) * fraction
}

Note that special cases like NaN, Infinity, etc. is not covered.

This was ported from: http://objectmix.com/perl/21834-ibm-32-bit-floating-point-conversion.html

Hallgrim
  • 15,143
  • 10
  • 46
  • 54
0

A small update to Hallgrim's solution, which allows to handle double-precision floats:

function ibm2js(buffer) {
    var sign = buffer[0] >> 7
    var exponent = buffer[0] & 0x7f
    var fraction = 0
    function bit(buffer, bit) {
        return buffer[Math.floor(bit / 8)] >> (7 - (bit % 8)) & 1
    }
    var denom = 1
    var totalBit = (buffer.length - 1) * 8
    for (var i = 0; i < totalBit; i++) {
        denom = denom * 2
        fraction += bit(buffer, 8 + i) / denom
    }
    return (1 - 2 * sign) * Math.pow(16.0, exponent - 64) * fraction
}
Dmitry.Kolosov
  • 635
  • 4
  • 8