1

I'm trying to write a function that would fetch me the number of decimal places after the decimal point in a floating-point literal using the answer as a reference from here.

Although this seems to work fine when tried in the browser consoles, in the Node.js environment while running test cases, the precision is truncated only up to 14 digits.

let data = 123.834756380650877834678
console.log(data) // 123.83475638065088

And the function returns 14 as the answer.

Why is the rounding off happening at rest? Is it a default behavior?

SagarM
  • 311
  • 4
  • 14
  • Basically, you can't expect any particular floating point number to "be" any one particular way. The value will be *somewhere close* to what you write in your literal, but there's never any guarantee that it will be *exactly* what you wrote in your literal. If you need that number to be exact or if you want to make any clear assertions about the number of decimal places in it, you don't want to use floats. – deceze Feb 12 '21 at 11:31
  • Is that an actual example? For me, “123.83475638065087” is printed, differing in the last digit. If your JavaScript implementation is printing “123.83475638065088”, it may be defective. When 123.834756380650877834678 is converted to the format JavaScript uses for floating-point, IEEE-754 binary64, the exact result is 123.834756380650873097692965529859066009521484375, and printing it with default formatting should produce “123.83475638065087”. (Default formatting prints just enough digits to uniquely distinguish the represented value.) – Eric Postpischil Feb 12 '21 at 11:34
  • Re “Although this seems to work fine when tried in the browser consoles”: Attempting to calculate the number of digits after the decimal point of “123.834756380650877834678” should not work in a JavaScript implementation, after it has been converted to the internal floating-point format. Please show example code, input data, and output. – Eric Postpischil Feb 12 '21 at 11:48
  • "the precision is truncated only up to 14 digits" --> 123.83475638065088 has 17 significant digits. With FP numbers, it is the leading significant digits that count, not the digits after the decimal point. – chux - Reinstate Monica Feb 12 '21 at 15:18

2 Answers2

4

The floating-point format used in JavaScript (and presumably Node.js) is IEEE-754 binary64. When 123.834756380650877834678 is used in source code, it is converted to the nearest representable value, which is 123.834756380650873097692965529859066009521484375.

When this is converted to a string with default formatting, JavaScript uses just enough digits to uniquely distinguish the value. For 123.834756380650873097692965529859066009521484375, this should produce “123.83475638065087”. If you are getting “123.83475638065088”, which differs in the last digit, then the software you are using does not conform to the JavaScript specification (ECMAScript).

In any case, the binary64 format does not have sufficient precision to preserve the information that the original numeral, “123.834756380650877834678”, has 21 digits after the decimal point.

The code you link to also does not and cannot compute the number of digits in an original numeral. It computes the number of digits needed to uniquely distinguish the value represented after conversion to binary64. For sufficiently short numerals without trailing zeros after the decimal point, this is the same as the number of digits after the decimal point in the original numeral. For others, it may not be.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

it is default behavior of JavaScript.I think it will be same in node.js.

in JS The maximum number of decimals is 17.

for more details take a look at here

harshasoysa
  • 45
  • 1
  • 5
  • 1
    The page you pointed to is incorrect; the maximum number of decimal digits is not 17. Each IEEE-754 binary64 value other than NaNs represents one number exactly, and some of those have more than 17 digits when represented in decimal, such as 123.834756380650873097692965529859066009521484375. – Eric Postpischil Feb 12 '21 at 11:35