Why is an integer literal followed by a dot a valid numeric literal in JavaScript? - javascript

In JavaScript it is valid to end an integer numeric literal with a dot, like so...
x = 5.;
What's the point of having this notation? Is there any reason to put the dot at the end, and if not, why is that notation allowed in the first place?
Update: Ok guys, since you mention floats and integers... We are talking about JavaScript here. There is only one number type in JavaScript which is IEEE-754.
5 and 5. have the same value, there is no difference between those two values.

I guess it is just compatibility with other C-like languages where the dot does matter.

You DO need the decimal point if you call a method on an integer:
5.toFixed(n) // throws an error
5..toFixed(n) // returns the string '5.' followed by n zeroes
If that doesn't look right, (5).toFixed(n), or 5.0.toFixed(n), will work, too.

That's a floating point number. Unlike any other language I've ever encountered, all numbers in Javascript are actually 64-bit floating numbers. Technically, there are no native integers in Javascript. See The Complete Javascript Number Reference for the full ugly story.

The correct answer in this case is, that it makes absolutely no difference.
Every number in JavaScript is already a 64bit floating point number.
The ". syntax" is only useful in cases where you can ommit the fixed part because it's 0:
.2 // Will end up as 0.2
-.5 // Will end up as -0.5
So overall it's just saving a byte, but it makes the code less readable at the same time.

What if it wouldn't be an integer, but a floating point literal?

Related

.toFixed() returns a string? how can I convert that to floating number

I tried with the example value x = 123,i want two precision. So, i use x.toFixed(2). Then i will get the output "123.00"
but i want the output as 123.00 which is floating number with decimals.
var x = 123
x.toFixed(2);
output: "123.00"
expected: 123.00
A floating point notation or decimal number is not something explicitly declared. When the decimal point has nothing after the point, i.e., .0 It becomes an integer.
The .toFixed() is just for aesthetic purposes only. It also helps you to rounds off to the number of decimals too.
2.50000 and 2.5 are the exact same number. If you want to keep trailing zeroes, you'll have to use a string.
When I try to do this on my Chrome Console:
You can see that even when you do a strict type-checking, the decimals are considered like comments by the JavaScript parser. It might be a bit unclear to understand for developers coming from statically typed or strongly typed languages like Java & C#, where you can have separate float and double types.
Related: JavaScript - Keep trailing zeroes.

Javascript toFixed() is not working as expected

I am using toFixed but the method does not operate as expected
parseFloat(19373.315).toFixed(2);
//19373.31 Chrome
Expected Output : 19373.32
parseFloat(9373.315).toFixed(2);
// 9373.32 Working fine
Why does the first example round down, whereas the second example round up?
The problem is that binary floating point representation of most decimal fractions is not exact. The internal representation of 19373.315 may actually be something like 19373.314999999, so toFixed rounds down, while 19373.315 might be 19373.315000001, which rounds up.
Why does the first example round down, whereas the second example round up?
Look at the binary representation of the two values in memory.
const farr = new Float64Array(2);
farr[0] = 19373.315;
farr[1] = 9373.315;
const uarr = new Uint32Array(farr.buffer);
console.log(farr[0], uarr[1].toString(2).padStart(32, 0) + uarr[0].toString(2).padStart(32, 0));
console.log(farr[1], uarr[3].toString(2).padStart(32, 0) + uarr[2].toString(2).padStart(32, 0));
Without diving into the details, we can see that the second value has an additional '1' at the end, which is lost in the first larger value when it is fit into 64 bits.
Other answers have explained why, I would suggest using a library like numeral.js which will round things as you would expect.
Assuming toFixed casts to 32-bit float;
Check with this utility...
19373.315 is stored as 19373.314453125 (an error of -0.000546875) in 32-bit floating point format.
This is despite (19373.315).toFixed(4) coming out as 19373.3150.
Even if this is "expected" or "intended", I'd still report it as a bug.
It should use a double during the rounding check, and thus proper rounding during conversion to fixed string.
I think the spec even says so. :\
In the V8 javascript engine source, the Number.prototype.toFixed function invokes DoubleToFixedCString in this file ...
There's probably some inappropriate optimization in there... (Looking into it.)
I'd suggest submitting an additional test case for V8 with 19373.315 specifically.
(19373.3150).toFixed(39) yields 19373.314999999998690327629446983337402343750.
Rounding occurs once to bring it up to 19373.315 - which is correct - but not at the right digit when rounding to 2 digits.
I think this should have a second pass on rounding here to catch edge cases like this. I think it might have to round to n+1 digits, then again to n digits. Maybe there's some other clever way to fix it though.
function toFixedFixed(a,n) {
return (a|0) + parseFloat((a % 1).toFixed(n+1)).toFixed(n).substr(1);
}
console.log(toFixedFixed(19373.315,2)); // "19373.32"
console.log(toFixedFixed(19373.315,3)); // "19373.315"
console.log(toFixedFixed(19373.315,4)); // "19373.3150"
console.log(toFixedFixed(19373.315,37)); // "19373.3149999999986903276294469833374023438"
console.log(toFixedFixed(19373.315,38)); // "19373.31499999999869032762944698333740234375"
console.log(toFixedFixed(19373.315,39)); // "19373.314999999998690327629446983337402343750"
(Adopted from my comments on Vahid Rahmani's answer, who is correct.)

Is `10e1` an Integer literal or Floating point literal?

I was looking into this article and wondering if 10e1 is an Integer Literal or a Floating Point Literal.
I know that 100 is an Integer literal. Does it make any difference if I write 10e1 instead?
When I check in the spec here(7) or here(5.1), there is nothing called "Floating Point Literal". Is this just another incorrect doc in MDN? Any idea what Floating Point Literal refers to?
To summarise:
Does 100 and 10e1 fall into same category of literals? If yes, which?
Is there something called "Floating Point Literal"?
Does it make any difference if I write 10e1 instead of 100?
Not for the result, no. But it's one character more to transfer and parse (so better use 1e2 :-D), and it will affect readability. Not everyone is familiar with exponents.
In the spec there is nothing called "Floating Point Literal". Is this just another incorrect doc in MDN?
The MDN guide is dubious for sure, naming a sections "Integers" in an article about JS types is confusing at least.
Does 100 and 10e1 fall into same category of literals? If yes, which?
Yes, they're both numeric literals. JS does not distinguish between numbers with and without a fractional part, they all have the same floating-point type. There is only one grammar for decimal number literals, with fractional digits and exponents being optional.
Any idea what Floating Point Literal refers to?
It's meant as "(number) literal for a floating-point number", just as "Integer literal" means "(number) literal for a floating-point number representing an integer".
DecimalLiteral::
DecimalIntegerLiteral.DecimalDigits(opt) ExponentPart(opt)
.DecimalDigits ExponentPart(opt)
DecimalIntegerLiteral ExponentPart(opt)
DecimalIntegerLiteral::
0
NonZeroDigitDecimalDigitsopt
As per spec, 100 and 10e1 are both "DecimalLiteral" while 100 also qualifies to be "DecimalIntegerLiteral"
None of these should make any real difference to the developer as mentioned in comments by #Thilo
The internal representation as per IEEE-754 should as well be the same.
Status Sign [1] Exponent [11] Significand [52]
Normal 0 (+) 10000000101 (+6) 1.1001000000000000000000000000000000000000000000000000 (1.5625)

why is 10 * (7/10) = 7 in JavaScript?

7 and 10 in the expression (7/10) are integers, so the result 0.7 should be integer as well, which is 0, and the result for the entire expression should be 0 too. However, it's giving me the result of 7, why? Is it ignoring the parentheses or converts to double automatically?
JavaScript doesn't distinguish between integers and floating point numbers, everything I believe is considered a double so that is just why you get the result.
Take a look at the details on the Number property on MDN.
JavaScript doesn't have an integer type, or a double, or a float... it just has 1 type for all numbers: the helpfuly called Number type (try var foo = new Number(7);, or var foo = Number('123string');
Now, I know I said that JS doesn't know of floats, but that's not entirely true. All Number type vars/values are, essentially 64 bit floats, as defined by the IEEE 754 standard (which are, indeed, as Jan Dvorak kindly pointed out to me, double's in most staticly typed languages), with all the caveats that brings with it:
(.1 + .2);//0.30000000000000004
But that's not the point. The point is that, in JS you can perform float + int arithmatic without there ever being a need for internal casts, or conversions. That's why 10*(7/10) will always be 7
There is no int and double in JavaScript
In JavaScript, both int, flot, and double are normalized to work together. They are treated as 1 (They're treated as as Number, which is an IEEE 754 float. Thanks #Elias Van Ootegem). Equality, Liberty and Fraternity. and thus;
10*0.7 = 7
JavaScript is not like C.
Javascript doesn't have integers, and even if it did, there's nothing that says that / needs to return an integer (just because another language may do that doesn't mean every language has to). The operation results in a float/Number, just like all Javascript numbers are, period.
try this
10*parseInt(7/10)
hope this will help you
If you try to follow the rules, then
10 * (7/10) --> 10 * .7 --> 7
You cannot change the way its gonna result into.
so the result 0.7 should be integer as well, which is 0
If you want this, then try using
Math.Floor();
This would change the decimals to the nearest int! Or try out parse()
JavaScript uses dynamic types. That means that a variable like this:
var str = "hi";
Can later become:
str = 123; //now we have an 'int'
str += 0.35; //now str is 123.35, a 'float'
So JavaScript doesn't cast floats to ints for example.
If you want to force a "cast" then you have to do:
var integer = parseInt( 3.14*9.0291+23, 10 ); //the second parameter (10) is the 'base'
But remember, Javascript will not take care of types, that's your problem.

Javascript alert number starting with 0

I have a button where in the code behind I add a onclick and I pass a unique ID which will be passed to the js function. The id starts with a 0.
It wasn't working and eventually I figured out that the number, id, it was passing was wrong...
Ie. see this: js fiddle
It works with a ' at the start and end of the number. Just wondering why 013 turns to 11. I did some googling and couldn't find anything...
Cheers
Robin
Edit:
Thanks guys. Yep understand now.
As in this case the 0 at the start has a meaning, here the recipient ID in a mailing list, I will use '013' instead of just 013, i.e. a string. I can then split the values in js as each of the 3 values represents a different id which will always be only 1 character long, i.e. 0-9.
A numeric literal that starts with a 0 is treated as an octal number. So 13 from base 8 is 11 in base 10...
Octal numeric literals have been deprecated, but still work if you are not in strict mode.
(You didn't ask, but) A numeric literal that starts with 0x is treated as hexadecimal.
More info at MDN.
In your demo the parameter is called id, which implies you don't need to do numerical operations on it - if so, just put it in quotes and use it as a string.
If you need to be able to pass a leading zero but still have the number treated as base 10 to do numerical operations on it you can enclose it in quotes to pass it as a string and then convert the string to a number in a way that forces base 10, e.g.:
something('013');
function something(id){
alert(+id); // use unary plus operator to convert
// OR
alert(parseInt(id,10)); // use parseInt() to convert
}
Demo: http://jsfiddle.net/XYa6U/5/
013 is octal, not decimal, it's equal 11 in decimal
You should note that 013 starts with a 0. In Javascript, this causes the number to be considered octal. In general you'll want to use the decimal, and hexadecimal number systems. Occasionally though, octal numbers are useful, as this question shows.
I hope this helps! :)
If the first digit of a number is a zero, parseInt interprets the number as an octal.
You can specify a base of ten like this:
parseInt(numberString, 10)
You could also remove such zeros with a regex like this (the result will be a string):
numberString.replace(/^0+/g, '');

Categories

Resources