question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Discussion: Float encoding

See original GitHub issue

At the risk of causing bikeshedding, I wanted to raise a point of discussion regarding how floats are encoded – given that integers are encoded in Base62 and therefore take up less space than their decimal form, it seems a bit odd that floats are left as-is.

My first idea was that they could also be encoded in a similar compacted form, such as base36, which JavaScript can do natively with .toString(36), but that isn’t particularly great if the float’s magnitude is not close to 0 because the expontent e+n notation can’t be used unambiguously, and parsing them back from such a format probably isn’t easy (definitely not in JavaScript.)

I’d love to hear more about the rationale behind this decision (if any)! All in all, for the goals that it sets out to accomplish, JCOF is really neat.

(Edit, this did end up causing bikeshedding, especially in the other issues, sorry for that.)

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
mortiecommented, Jul 16, 2022

A proper float to string algorithm doesn’t just choose some number of sufficient digits; the string "2.2" represents exactly the one floating point number which is the closest to being 2.2, and a float parser will return that exact floating point value when parsing "2.2". And the expression 1/3 returns a floating point value; (1/3).toString() returns the shortest string representation where (1/3) is the closest float, so that the float parser returns the exact same float.

My problem is that I only know about these challenges, not how they’re solved, or even how difficult they are to solve.

FWIW, I tried out the algorithms in https://observablehq.com/d/e3010313d892b36e, and a lot of numbers aren’t round-tripped correctly. For example, the base 10 float 1.1344e-319 stringifies to "f2WY-5d", which parses to 1.12094e-319, and 9.399999999999983 stringifies to "fH3egP4fQc-f" which parses to 9.399999999999984.

Here’s a snippet which can be used to test all the floats:

// Return the next representable double from value towards direction
// From https://stackoverflow.com/a/27661477
function nextNearest(value) {
  if (!isFinite(value))
    return value;
  
  var buffer = new ArrayBuffer(8);
  var f64 = new Float64Array(buffer);
  var u32 = new Uint32Array(buffer);
  
  f64[0] = value;
  
  if (value === 0) {
    u32[0] = 1;
    u32[1] = 0;
  } else if ((value > 0) && (value < Infinity) || (value < 0) && (value > Infinity)) {
    if (u32[0]++ === 0xFFFFFFFF)
      u32[1]++;
  } else {
    if (u32[0]-- === 0)
      u32[1]--;
  }
  
  return f64[0];
}

let f = 0;
while (f != Infinity) {
  let str = stringifyF62(f);
  let parsed = parseF62(str);
  if (parsed == f) {
    console.log("OK:", f, "from string", str);
  } else {
    console.log("ERR: expected", f, "got", parsed, "from string", str);
  }

  f = nextNearest(f);
}

Replace with stringifyF62(f) with f.toString() and parseF62(str) with parseFloat(str), and you can see that the JavaScript float stringify and parse functions round-trip all numbers you try perfectly.

0reactions
JobLeonardcommented, Jul 16, 2022

… actually, given how I currently coded it we could replace i, I, f and F prefixes with a universal n and N prefix, since the optional ., ,, + and - separators can be used to indicate if we’re dealing with a pure integer or with a floating point number.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Floating Point Representation - Basics - GeeksforGeeks
The discussion confines to single and double precision formats. ... Depending on base and the number of bits used to encode various ...
Read more >
Encoding a floating point value - binary - Math Stack Exchange
Assuming a standard IEEE 32 bits we have: 8 bits of exponents; 23 bits of mantissa; 1 bit of sign. Your expansion 0.111...
Read more >
What Every Computer Scientist Should Know About Floating ...
The discussion of the standard draws on the material in the section ... and emax - emin + 1 possible exponents, a floating-point...
Read more >
A Tutorial on Data Representation - Integers, Floating-point ...
The moral of the story is unless you know the encoding scheme, there is no way that you can decode the ... Floating-point...
Read more >
Floating-point arithmetic - Wikipedia
In computing, floating-point arithmetic (FP) is arithmetic that represents real numbers approximately, using an integer with a fixed precision, called the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found