3

I have do some test about Number.prototype.toFixed method in chrome(v60.0.3112.101) console and found sth puzzled me.

Why 1.15.toFixed(1) return "1.1" but not the "1.2"?
Why 1.05.toFixed(1) return "1.1" but not the "1.0"?
and so on... test on the chrome console


I do research in the ECMAScript specification.

NOTE 1 toFixed returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed.

I know what's the fixed point notation.But I can't explain the puzzles above. Could someone give a clear explaination?


BTW, I think the details arithmetic under the specification should be improved. Saying 1.105 for instance, the relative arithmetic is the following:

Let n be an integer for which the exact mathematical value of n ÷ 10^f - x is as close to zero as possible. If there are two such n, pick the larger n.

According to pick the larger n, 111 should be taken into consideration but not the 110, which is contradicted to reality.

Ye Shiqing
  • 1,519
  • 2
  • 15
  • 24
  • the referenced specification does not say anything about rounding, there are other methods to round a number. why do you expect this method to perform any rounding? – Oleg Estekhin Aug 23 '17 at 02:53
  • rounding in javascript will always round `n.m5` UP when rounding to 1 decimal for example – Jaromanda X Aug 23 '17 at 02:53
  • 1
    in reality numbers are stored using double-precition floating point ( https://en.wikipedia.org/wiki/Double-precision_floating-point_format ),(1.15).toExponential(20) gives "1.14999999999999991118e+0" - and so it is closer to "1.1"; (1.05).toExponential(20) gives "1.05000000000000004441e+0" - it is closer to "1.1" – 4esn0k Aug 23 '17 at 02:59
  • @JaromandaX of course, but the toFixed method is not the same with simple rounding.And `Math.round` method only round a number to the nearest integer. – Ye Shiqing Aug 23 '17 at 03:00
  • @4esn0k Well, but why u let exponent be 20 for test instead of a number less than it? – Ye Shiqing Aug 23 '17 at 03:11
  • 1
    @PageYe I am using `Number#toExponent(20)` only to show something closer to the really stored number value – 4esn0k Aug 23 '17 at 05:07

1 Answers1

0

I'll try my best to clarify the points around that question. First of all the fixed-point notation:

I know what's the fixed point notation. But I can't explain it well.

The fixed-point natation is opposed to the floating point notation. The floating point notation allow a better precision most of the time. But it also is more difficult to understand and to compute.

Well, let's go back to the fixed-point notation. This is also an arithmetic notation for real numbers. The difference is that a number in fixed-point notation is represented by an integer with a scaling factor. For example :

If you want to write 4.56 and you got a 1/1000 scaling factor, your number will be represented by 4560. Indeed, 4560 * (1/1000) = 4.56

Now that we know how does the fixed-point notation does work, we can better understand the results of the toFixed(n) function. Let's say for the example that the scaling factor is 1/1000 (that is not the real value but this is easier to visualise the results).

1.15.toFixed(1)

Will take on decimal and then represent the number with a fixed-point notation, so it does not care about the '5'. The number you got in memory is 1100. This is why the number is rounded to the closest inferior value.

Now as you can see on the MDN Doc of toFixed function the you can keep up to 20 decimals. From that information we can say that the scaling factor is 1/10^20.

I hope that answers your questions.