Number(123.456).toFixed(20)
emits
"123.45600000000000306954"
Where does 306954
come from? I know that numbers that are represented in binary, cant be accurate. But I didn't find any mention in the documentation that calling number(/.../) would result in a loss of precision.
mdn says
A string representation of number that does not use exponential notation and has exactly digits digits after the decimal place. The number is rounded if necessary, and the fractional part is padded with zeros if necessary so that it has the specified length. If number is greater than 1e+21, this method simply calls Number.toString() and returns a string in exponential notation
toFixed returns Fixed point and not floating point ...
This is entirely to do with floating point representation of decimal numbers.
Computers cannot represent 123.456
exactly, so the nearest binary number is used instead.
See the floating point guide, or for more details What Every Computer Scientist Should Know About Floating-Point Arithmetic.
As per the first link, there is no built-in solution (i,.e. a decimal type) in Javascript. There is a port of Java's BigDecimal
class available, if this is a real issue for you rather than a matter of curiousity.
Reponse to edit: This isn't a problem with Number
. In your working example, you declare an integer literal (123
) - these can be represented exactly. In your failing example, you use a floating point literal 123.456
, which at the moment it's processed by the runtime will be represented by a sequence of binary digits that are not exactly 123.456
.
The problem is with floating point literals, not Number
itself.