All files / asm80-core/utils fp.js

100% Statements 58/58
100% Branches 32/32
100% Functions 2/2
100% Lines 58/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 581x 1x 1x 1x 1x 1x 1x 1x 26x 26x 26x 26x 26x 26x 2x 2x 2x 24x 24x 24x 22x 22x 22x 704x 704x 704x 108x 108x 108x 704x 704x 704x 704x 704x 704x 88x 88x 88x 704x 22x 24x 24x 24x 24x 26x 26x 22x 22x 22x 26x 1x 26x 21x 21x 22x 22x 22x 1x
/**
 * Convert a number to ZX Spectrum floating-point format (5 bytes)
 * @param {number} num - Number to convert
 * @param {boolean} [simpleint=true] - If true, integers are stored as simple integers when possible
 * @returns {number[]} Array of 5 bytes representing the number in ZX format [exponent, byte0, byte1, byte2, byte3]
 * @throws {Error} When number is too large (overflow)
 */
export const fptozx = (num, simpleint) => {
    simpleint = simpleint === undefined ? true : simpleint;
    let sgn = num < 0;
    let m = sgn ? -num : num;
    
    // Handle integers in range -65535 to 65535 as simple format
    if (simpleint && num == Math.floor(num) && num >= -65535 && num <= 65535) {
      m = sgn ? 65536 + num : num;
      return [0, sgn ? 0xff : 0, m & 0xff, (m >> 8) & 0xff, 0];
    }
    
    // Generate 32-bit mantissa representation
    let bit32 = function (m, sgn) {
      let out = "";
      let a = [];
      for (let i = 0; i < 32; i++) {
        let bit = "0";
        m = m * 2;
        if (m >= 1.0) {
          m -= 1.0;
          bit = "1";
        }
        // Set sign bit at position 0
        if (sgn && i === 0) bit = "1";
        if (!sgn && i === 0) bit = "0";
        out += bit;
        // Convert each 8-bit chunk to byte
        if (i % 8 == 7) {
          a.push(parseInt(out, 2));
          out = "";
        }
      }
      return a;
    };
    
    // Calculate exponent
    let e = Math.floor(Math.log2(m) + 1);
    if (e > 127) throw new Error("Overflow");
    if (e < -127) return [0, 0, 0, 0, 0]; // Underflow to zero
    
    // Normalize mantissa to range [0.5, 1)
    let i;
    if (e < 0) {
      for (i = 0; i < -e; i++) m = m * 2;
    } else {
      for (i = 0; i < e; i++) m = m / 2;
    }
    
    let n = bit32(m, sgn);
    return [e + 128, n[0], n[1], n[2], n[3]]; // Bias exponent by 128
  };