Why parseInt() doesn't convert "true" to number, while multiplying does? [duplicate] - javascript

This question already has answers here:
parseInt vs unary plus, when to use which?
(6 answers)
Closed 8 years ago.
I started from expression returning true (I choose 1==1) and wrote it in console
cosole.log(1==1);
It logs true. Now I want to convert it to integer (1) and wrap it in parseInt()
console.log(parseInt(1==1));
It logs NaN. Looks like it is trying to convert 1==1 to string before it converts it to number.
Then I'll simply multiply 1==1 by 1.
console.log((1==1)*1);
It logs 1.
Why in first case it converts it converts true to string before converting it to integer (resulting NaN) while I want to convert it to string and in the second case it converts true directly to integer? I'd expect that true*1 will be NaN too.

parseInt, by virtue of being a “parse”r, should take a string and produce an integer, so it converts its argument to a string. *, because it’s multiplication, converts its arguments to numbers.
If you want to convert anything to an (32-bit) integer, | 0 works; it’s a 32-bit bitwise integer operation, and can’t result in NaN, because that’s not a 32-bit integer.
Just to emphasize that parseInt is a wholly inappropriate way of casting anything but a string to an integer: what does this give you?
parseInt(5000000000000000000000000)
(For numbers that big, use Math.round(x), or Math.round(+x) if you like to be explicit.)

parseInt(bool) == NaN
parseInt(bool*1) == parseInt(int) == int
I believe Javascript makes true = 1 and false = 0 when you multiply it.
EDIT: to further this, parseInt(bool*bool) would also work

Related

Numeric conversion in JavaScript [duplicate]

How do parseInt() and Number() behave differently when converting strings to numbers?
Well, they are semantically different, the Number constructor called as a function performs type conversion and parseInt performs parsing, e.g.:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Also parseInt will ignore trailing characters that don't correspond with any digit of the currently used base.
The Number constructor doesn't detect implicit octals, but can detect the explicit octal notation:
Number("010"); // 10
Number("0o10") // 8, explicit octal
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
And it can handle numbers in hexadecimal notation, just like parseInt:
Number("0xF"); // 15
parseInt("0xF"); //15
In addition, a widely used construct to perform Numeric type conversion, is the Unary + Operator (p. 72), it is equivalent to using the Number constructor as a function:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
first two will give you better performance as it returns a primitive instead of an object.
One minor difference is what they convert of undefined or null,
Number() Or Number(null) Or Number('') // returns 0
while
parseInt() Or parseInt(null) // returns NaN
Summary:
parseInt():
Takes a string as a first argument, the radix (An integer which is the base of a numeral system e.g. decimal 10 or binary 2) as a second argument
The function returns a integer number, if the first character cannot be converted to a number NaN will be returned.
If the parseInt() function encounters a non numerical value, it will cut off the rest of input string and only parse the part until the non numerical value.
If the radix is undefined or 0, JS will assume the following:
If the input string begins with "0x" or "0X", the radix is 16 (hexadecimal), the remainder of the string is parsed into a number.
If the input value begins with a 0 the radix can be either 8 (octal) or 10 (decimal). Which radix is chosen is depending on JS engine implementation. ES5 specifies that 10 should be used then. However, this is not supported by all browsers, therefore always specify radix if your numbers can begin with a 0.
If the input value begins with any number, the radix will be 10
Number():
The Number() constructor can convert any argument input into a number. If the Number() constructor cannot convert the input into a number, NaN will be returned.
The Number() constructor can also handle hexadecimal number, they have to start with 0x.
Example:
console.log(parseInt('0xF', 16)); // 15
// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10)); // 10
// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));
console.log('\n');
// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));
// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));
// scientific notation is allowed
console.log(Number('152e-1')); // 15.21
If you are looking for performance then probably best results you'll get with bitwise right shift "10">>0. Also multiply ("10" * 1) or not not (~~"10"). All of them are much faster of Number and parseInt.
They even have "feature" returning 0 for not number argument.
Here are Performance tests.
I found two links of performance compare among several ways of converting string to int.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
http://jsben.ch/#/zGJHM
http://phrogz.net/js/string_to_number.html
parseInt() -> Parses a number to specified redix.
Number()-> Converts the specified value to its numeric equivalent or NaN if it fails to do so.
Hence for converting some non-numeric value to number we should always use Number() function.
eg.
Number("")//0
parseInt("")//NaN
Number("123")//123
parseInt("123")//123
Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string
Number(true)//1
parseInt(true) //NaN
There are various corner case to parseInt() functions as it does redix conversion, hence we should avoid using parseInt() function for coersion purposes.
Now, to check weather the provided value is Numeric or not,we should use nativeisNaN() function
I always use parseInt, but beware of leading zeroes that will force it into octal mode.
It's a good idea to stay away from parseInt and use Number and Math.round unless you need hex or octal. Both can use strings. Why stay away from it?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
It completely butchers really large or really small numbers. Oddly enough it works normally if these inputs are a string.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Instead of risking hard to find bugs with this and the other gotchas people mentioned, I would just avoid parseInt unless you need to parse something other than base 10. Number, Math.round, Math.floor, and .toFixed(0) can all do the same things parseInt can be used for without having these types of bugs.
If you really want or need to use parseInt for some of it's other qualities, never use it to convert floats to ints.
parseInt converts to a integer number, that is, it strips decimals. Number does not convert to integer.
Another way to get the result is to use the ~ operator
For most circumstances
~~someThing === parseInt(something)
but ~~ will return zero for strings that parseInt will accept with trailing other characters or with the number base spec (eg hex) and will also return zero when parseInt returns NaN. Another difference is that ~~ if given a bigint returns a bigint to which you can add another bigint whereas parseInt returns an ordinary floating point number (yes really - it gives exactly the same value as parseFloat) if the bigint is large
However for most circumstances ~~ is 30% faster than parseInt. It is only slower by 10% when something is a floating point represented as a string.
So if the more restricted scope of ~~ fits your need then save the computer time and give yourself less to type

ParseInt() strange octal behavior [duplicate]

This question already has answers here:
Why JavaScript treats a number as octal if it has a leading zero
(3 answers)
Closed 4 years ago.
I have to convert some input data to integer.
I found parseInt() function.
Everything is good if the input is string:
console.log(parseInt("123")) //123
Even if the string starts with 0:
console.log(parseInt("0123")) //123
But if a number starts with 0, it will give 83!
console.log(parseInt(0123)) //83 instead of 123
I heard about that's because octal behavior (Javascript parseInt() with leading zeros), so I gave a radix parameter to it:
console.log(parseInt(0123,10)) //83!!!
Still 83!!!
And then, the strangest of all:
I thinked: octal 123 must give 123 in octal!
But it gave NaN:
console.log(parseInt(0123, 8)) //NaN
Why this strange behavior?! And how can I fix it?
Thanks!!!
In this code, you can defined a number (rather than a string) in octal format, then passed it to parseInt. Then parseInt casts that number to a string ("83"), and parses it again.
If you pass a string to parseInt you will get the expected result:
console.log(parseInt('0123'))
You should use a combination of a string and a radix to get the correct value. Here's an example:
parseInt(01234) // returns 668
parseInt('01234', 10) // returns 1234

What exactly does isNaN() do in javaScript? [duplicate]

This question already has answers here:
Is Number.IsNaN() more broken than isNaN()
(11 answers)
Closed 7 years ago.
isNaN() returns false if and only if the argument is number.
var a = new Number(1);
By doing so, a is an object now.
So why is isNaN(a) returning false?
isNaN() tests whether an input is NOT a number.
var a = new Number(1)
a is a number object. Therefore isNaN() returns false.
Here is a nice documentation containing isNaN() behaviors with different edge cases. Unfortunately some of them are not as intuitive as hoped, so it's worth reading.
The global isNaN() function coerces its argument to a number value before testing for NaN. Your object converts cleanly to the number 1, and 1 is not NaN.
Note that isNaN("1") also returns false, because the string "1" converts cleanly to a number that isn't NaN.
The isNaN function is not really intended as a general-purpose test for whether something is or is not a number. It's a test for the specific numeric value NaN. It's often used as a general-purpose test, and that (mostly) works because JavaScript returns NaN when an attempt to convert a value to a number fails. That's somewhat impure, because NaN exists as a marker with a specific purpose in the floating point system.
Some JavaScript environments have Number.isNaN() in addition to the global isNaN. The function on the Number constructor does not perform a type coercion first. For that reason, Number.isNaN("foo") returns false, because even though the string "foo" cannot be converted to a number cleanly, it's not the constant NaN.

parseInt('1e1') vs parseFloat('1e1')

parseInt(1e1); //10
parseInt('1e1'); //1
parserFloat('1e1') //10
Why parseInt returns 1 in the second case? The three shouldn't return the same result?
1e1 is a number literal that evaluates to 10; parseInt() sees 10 and happily returns that.
'1e1' is a string, and parseInt() does not recognize exponential notation, so it stops at the first letter.
'1e1' as a string is perfectly fine when parsed as a float.
Bonus: parseInt('1e1', 16) returns 481, parsing it as a 3-digit hex number.
When you're trying to parse a string, only the first number in a string is returned. Check function specification at http://www.w3schools.com/jsref/jsref_parseint.asp
Also, you can test it out yourself:
parseInt('2e1') - returns 2
parseInt('3e2') - returns 3
To understand the difference we have to read ecma official documentation for parseInt and parseFloat
... parseInt may interpret only a leading portion of string as an integer value; it ignores any characters that cannot be interpreted as part of the notation of an integer, and no indication is given that any such characters were ignored...
... parseFloat may interpret only a leading portion of string as a Number value; it ignores any characters that cannot be interpreted as part of the notation of an decimal literal, and no indication is given that any such characters were ignored...
parseInt expects ONLY an integer value (1, 10, 28 and etc), but parseFloat expects Number. So, string "1e1" will be automatically converted to Number in parseFloat.
parseInt('1e1'); // 1
parseFloat('1e1'); // 10

What's the function of the "|" (pipe) operator? [duplicate]

This question already has answers here:
Using bitwise OR 0 to floor a number
(7 answers)
Closed 8 years ago.
I have this line that I copied from another place:
Total += parseFloat($(this).val())|0;
What's the function of the operator |? When I change the number, I get different results.
The | in JavaScript is an integer bitwise OR operator. In that context, it strips off any fractional portion returned by parseFloat. The expression parseFloat($(this).val()) will result in a number with (potentially) a fractional component, but then |0 will convert it to an integer number, OR it with 0 (which means it won't change), and so the overall result is to get a whole number.
So functionally, it truncates the fractional portion off the number. -1.5 becomes -1, and 1.5 becomes 1. This is like Math.floor, but truncating rather than rounding "down" (Math.floor(-1.5) is -2 — the next lowest whole number — rather than -1 as the |0 version gives us).
So perhaps that's why it was used, to chop off (rather than "floor") the fractional portion of the number.
Alternately, it could be a typo. The author of that code might have meant to write this (note || rather than |):
Total += parseFloat($(this).val()) || 0;
That defends against the possibility that $(this).val() returns "" or similar, resulting in parseFloat returning NaN. It uses the curiously-powerful || operator to return 0 rather than NaN in that case. (And there's an advertisement for putting spaces around your operators.) Would have to know the context of the code to say whether truncating to a whole number (|) makes sense when adding to Total, or if they were just defending the NaN case.
The | operator in javascript is the bitwise or operator
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators
This operator treats the operands as 32 bit integers and for every bit returns 1 if either is 1 and 0 otherwise.

Categories

Resources