Skip to main content

FMT_F64_JS

Constant FMT_F64_JS 

Source
pub const FMT_F64_JS: &str = "const fmtF = (v) => {
  if (Number.isNaN(v)) return 'NaN';
  if (v === Infinity) return 'inf';
  if (v === -Infinity) return '-inf';
  if (v === 0) return Object.is(v, -0) ? '-0' : '0';
  const sign = v < 0 ? '-' : '';
  const a = Math.abs(v);
  const s = a.toString();
  const e = s.indexOf('e');
  const mantissa = e < 0 ? s : s.slice(0, e);
  const dot = mantissa.indexOf('.');
  let digits = dot < 0 ? mantissa : mantissa.slice(0, dot) + mantissa.slice(dot + 1);
  let point = (dot < 0 ? mantissa.length : dot) + (e < 0 ? 0 : Number(s.slice(e + 1)));
  const lead = digits.length - digits.replace(/^0+/, '').length;
  digits = digits.slice(lead).replace(/0+$/, '');
  point -= lead;
  const spell = (d, p) => p <= 0 ? '0.' + '0'.repeat(-p) + d : p >= d.length ? d + '0'.repeat(p - d.length) : d.slice(0, p) + '.' + d.slice(p);
  if (Number(spell(digits + '5', point)) === a) {
    const view = new DataView(new ArrayBuffer(8));
    view.setFloat64(0, a);
    const bits = view.getBigUint64(0);
    const biased = Number(bits >> 52n);
    const m = biased === 0 ? bits & 0xfffffffffffffn : (bits & 0xfffffffffffffn) | (1n << 52n);
    const b = biased === 0 ? -1074 : biased - 1075;
    const q = point - digits.length - 1;
    const half = BigInt(digits + '5') * 10n ** BigInt(Math.max(q, 0)) * 2n ** BigInt(Math.max(-b, 0));
    const exact = m * 2n ** BigInt(Math.max(b, 0)) * 10n ** BigInt(Math.max(-q, 0));
    if (half === exact) {
      const up = (BigInt(digits) + 1n).toString();
      point += up.length - digits.length;
      digits = up.replace(/0+$/, '');
    }
  }
  return sign + spell(digits, point);
};";
Expand description

A float as LOGOS shows it, in the JavaScript every WebAssembly host runs: the display logicaffeine_data::fmt::fmt_f64 defines, byte for byte. ECMAScript’s Number.prototype.toString gives the shortest digits that read back to the same bits, as Rust’s {} does, except where the double lies exactly halfway between two shortest candidates: ECMAScript takes the even one and Rust the larger, so an exact tie (screened by parsing, settled with the double’s exact binary value in BigInt) moves up. The digits are spelled without exponent notation, an integral value bare, and NaN, inf, -inf and -0 as Rust spells them. The node shim interpolates it and runtime.js carries the same text (wasm_float_display_lock).