javascript, parseInt behavior when passing in a float number - javascript

I have the following two parseInt() and I am not quite sure why they gave me different results:
alert(parseInt(0.00001)) shows 0;
alert(parseInt(0.00000001)) shows 1
My guess is that since parseInt needs string parameter, it treats 0.00001 as ""+0.00001 which is "0.00001", therefore, the first alert will show 0 after parseInt. For the second statement, ""+0.00000001 will be "1e-8", whose parseInt will be 1. Am I correct?
Thanks

I believe you are correct.
parseInt(0.00001) == parseInt(String(0.00001)) == parseInt('0.00001') ==> 0
parseInt(0.00000001) == parseInt(String(0.00000001)) == parseInt('1e-8') ==> 1

You are correct.
parseInt is intended to get a number from a string. So, if you pass it a number, it first converts it into a string, and then back into a number. After string conversion, parseInt starts at the first number in the string and gives up at the first non-number related character. So "1.e-8" becomes "1"
If you know you are starting with a string, and are just trying to get an Integer value, you can do something like.
Math.round(Number('0.00000001')); // 0
If you know you have a floating point number and not a string...
Math.round(0.00000001); // 0
You can also truncate, ceil(), or floor the number

parseInt takes each character in the first argument (converted to a string) that it recognizes as a number, and as soon as it finds a non-numeric value it ignores that value and the rest of the string. (see MDN second paragraph under "Description")
Therefore it's likely that parseInt(0.00000001) === parseInt(String(0.00000001)) === parseInt("1e-8"), which would only extract the 1 from the string yielding parseInt("1") === 1
However, there's another possibility:
From Mozilla developer network:
parseInt(string, radix);
for the string argument (emphasis added): "The value to parse. If string is not a string, then it is converted to one. Leading whitespace in the string is ignored."
I think this possibility is less likely, since String(0.00000001) does not yield NAN.

Related

Why does parseInt(string#2019) return NaN in JavaScript?

I am new to JavaScript and currently understand two things about the parseInt() method:
parseInt("100") // gives 100
parseInt("2019#string") // gives 2019
However, why would parseInt("string#2019") give NaN?
You can see the issue if you look at the W3Schools page for parseInt:
If the first character cannot be converted to a number, parseInt() returns NaN.
This is why the following returns NaN:
console.log(parseInt("O123"));
But if you have multiple numbers in a string, separated by a non-digit character, then it will not error - it'll just return the first number:
Only the first number in the string is returned!
console.log(parseInt("12b34"));
This information is also found in the MDN page for parseInt:
If the first character cannot be converted to a number, NaN is returned.
The parseInt function takes in a string as an input, and tries to convert it to a number. Here are some examples that use parseInt to convert a string to a number. Your second example parseInt("string#2019") returns NaN because it string#2019 is not a valid type. Try just doing parseInt("2019").
You can read more about parseInt here.

String To Number Confusion

Why does parseInt("-1000-500-75-33") return -1000?
Shouldn't it return the sum of those numbers: -1608
How can I get the string "-1000-500-75-33" to return as the sum of those numbers?
parseInt will try to get a number starting from the beginning of the string.
Since - is a valid character to begin a number with, it parses the string until it finds something invalid. The second - is invalid because no integer can contain an - inside it, only digits. So it stops there and considers the number to be "finished".
Now, if you want to process the expression, you can use eval like so:
eval("-1000-500-75-33")
This will return -1608 as expected.
parseInt will not perform any computations, rather it will try to convert a string into an integer. It returns -1000 because the dash afterwards would not be considered a valid number. If you want to sum all these numbers you could split on the dash, map to Number, then reduce:
var numString = "-1000-500-75-33";
numString.split('-').map(e => Number(e)).reduce((a, b) => a - b);
Try to eval! it's safe here
eval("-1000-500-75-33").toString()
console.log(eval("-1000-500-75-33").toString());
And about type casting: After parsing -1000, which is obviously "negative 1000", It will escape casting as soon as it detect a symbol common between numbers & strings. So parseInt is seeing "-1000-500-75-33" as "-1000NotConvertableString", So left the remaining away, returning -1000 as the result of type-casting.
Since they are in a string, ParseInt does not parse the whole string, just finds the first applicable number from the start & returns it. If the start of the string cannot be parsed, it returns NaN
parseInt("-1000NOT_NUMBER") = -1000
parseInt("test-1000`) = NaN
You have to use eval function to do what you want, that evaluates given string as if it were a command entered into the console;
eval("-1000-500-75-33") = -1608

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

Bug in use of slice() has no effect?

I noticed that the correct
return str.slice(0, res);
returns the same value as the incorrect
var str = "some_string";
return str.slice(str, res);
In this case str is a string and res is a numeric quantity.
My guess is that some how because slice expects a numeric quantity and does not get one ( for the first parameter ), it converts what it finds to a 0.
Is this expected behavior?
JavaScript provides implicit type coercion. That means if an integer is expected (as is the case here), it will convert the value provided to an integer. If no sensible value can be divined, zero is used.
If an integer is provided, great!
If a string is provided and it looks like a integer (e.g. str.slice("5", res)) it will be converted into the expected integer.
If a string is provided and it doesn't look like a number (e.g. str.slice("abc", res)), 0 is used.
My guess is that some how because slice expects a numeric quantity and does not get one ( for the first parameter ), it converts what it finds to a 0.
That's basically what happens. .slice calls ToInteger on the first argument, which in turn calls ToNumber. But if the value cannot be converted to a number (if the result is NaN), it returns 0.
So, if you pass a numeric string as start, .slice would start at the mathematical value of that string. Any other string converts to 0.

Why is the number converted to a string (basic Javascript function)

I have this function (going trough the Eloquent Javascript Tutorial chapter 3):
function absolute(number) {
if (number < 0)
return -number;
else
return number;
}
show(absolute(prompt("Pick a number", "")));
If I run it and enter -3 the output will be 3 as expectet but if I enter just 3 the output will be "3" (with double quotes). I can get around by changing
return number;
to
return Number(number);
but why is that necessary? What am I missing?
prompt() always returns a string, but when you enter a negative number, it is handed to the -number call and implicitly converted to a Number. That doesn't happen if you pass it a positive, and the value received by prompt() is returned directly.
You can, as you discovered, cast it with Number(), or you can use parseInt(number, 10), or you could do -(-number) to flip it negative, then positive again, or more obviously as pointed out in comments, +number. (Don't do --number, which will cast it to a Number then decrement it)
Javascript is not strongly typed.
number comes from the prompt() function, which returns a string.
Since you aren't doing anything to change its type, it remains a string.
-number implicitly converts and returns an actual number.
If you have a string that needs to be converted to a number, please do the following:
var numString = '3';
var num = parseInt(numString);
console.log(num); // 3
JavaScript performs automatic conversion between types. Your incoming "number" is most likely string (you can verify by showing result of typeof(number)).
- does not take "string" as argument, so it will be converted to number first and than negated. You can get the same behavior using unary +: typeof(+ "3") is number when typeof("3") is string.
Same happens for binary - - will convert operands to number. + is more fun as it work with both strings "1"+"2" is "12", but 1+2 is 3.

Categories

Resources