1

I know that floating point values in JavaScript are stored with a binary base-2 format specified in IEEE 754. To me, this means that when I assign the literal value .1 to a variable, the value actually stored will be 0.100000001490116119384765625 (or some high-precision number like that--my math may be wrong).

But counter to that assumption, the console.log of a stored value does not reflect this. The following code: var a = 0.1; console.log(a);

...when executed in Chrome, and probably other browsers, will output: 0.1

I would have expected it to be: 0.100000001490116119384765625

Does the value of a at this point hold 0.1 or 0.1000000...? If the latter, then by what means does console.log() show 0.1? I'm interested in what's going on under the hood here. (E.g. Is JS storing a text representation of the number in the variable?)

For you diligent admins that might be a little quick to "mark as duplicate", please note that I am asking the opposite of the more common question and variations "Why do I suddenly see these wacky high-precision numbers?"

Erik Hermansen
  • 2,200
  • 3
  • 21
  • 41
  • 1
    Educated guess - the default precision of Number -> string conversions is insufficient to show these trailing digits. This is pretty common in other languages (e.g. `printf` in C defaults to 6 decimal places). – Oliver Charlesworth Apr 07 '18 at 20:00

2 Answers2

5

JavaScript’s default formatting of floating-point values uses just enough decimal digits to uniquely distinguish the value from neighboring floating-point values.

This question is a duplicate except it uses console.log, which is outside of JavaScript. The standard for JavaScript, the ECMAScript 2017 Language Specification does not mention console. This feature is provided by vendors as an extension. So each vendor may implement their own behavior. However, it is somewhat likely that using console.log with a Number will use the usual ToString behavior, resulting in the conversion explain in the answer linked above.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    I *think* it's simpler than that - `console.log` probably just invokes string conversion on its arguments, as opposed to knowing anything special about numbers. – Oliver Charlesworth Apr 07 '18 at 20:08
  • @OliverCharlesworth: To be complete, that needs to be shown, by citing the standard. I am on a phone at the moment, so finding things in the standard is awkward. – Eric Postpischil Apr 07 '18 at 20:13
  • @OliverCharlesworth, I thought about that. But in my code example, I first assigned the value to a variable to specifically prove that it wasn't console.log() trivially outputting a string conversion. It seems to me that the variable must store a string representation. – Erik Hermansen Apr 07 '18 at 20:14
  • Okay, I can see now why it doesn't have to be stored as a string representation. Oliver, you gave another explanation which seems more plausible, the string conversion chops off after 6 digits or something like that. – Erik Hermansen Apr 07 '18 at 20:21
  • @EricPostpischil, I read through your linked answer above, (nice work) and the ToString() operation from the ECMA spec explains the formatting I saw. Console logging seems outside of the ECMA standard. I found this informal spec https://console.spec.whatwg.org/#printer which would seem to indicate it's up to the browser implementation. And I would guess most (all?) of them would use the ECMA-defined ToString(). – Erik Hermansen Apr 07 '18 at 20:41
  • @ErikHermansen - I'm not sure I follow - what do you mean by "it wasn't console.log() trivially outputting a string conversion"? – Oliver Charlesworth Apr 07 '18 at 20:49
  • @OliverCharlesworth, I think my logic was flawed in the "it wasn't console.log() trivially outputting" statement. I'm agreeing with what you said in the first comment at this point. – Erik Hermansen Apr 07 '18 at 21:22
2

You are right! Neverthless I never noticed that and can't explain it. Maybe some different does. I assume it's just not shown, because it would irritate many people and for most stuff it's not an issue.

var a = 0.1;
console.log(a.toPrecision(21))
Paul
  • 2,086
  • 1
  • 8
  • 16
  • 1
    This should be a comment. Per the current [*ECMA-262 standard*](http://ecma-international.org/ecma-262/8.0/#sec-number.prototype.toprecision), if the precision parameter is greater than 21, a range error exception is thrown. In [*ECMAScript 2019*](https://tc39.github.io/ecma262/#sec-number.prototype.toprecision), it will be increased to 100 but you can't expect that to be widely implemented yet. – RobG Apr 07 '18 at 20:55