why do I get 24 when adding 2 + 4 in javascript - javascript

I am trying this:
function add_things() {
var first = '2';
var second = '4';
alert(first + second);
}
But it gives me 24 instead of 6, what am I doing wrong?

You're concatenating two strings with the + operator. Try either:
function add_things() {
var first = 2;
var second = 4;
alert(first + second);
}
or
function add_things() {
var first = '2';
var second = '4';
alert(parseInt(first, 10) + parseInt(second, 10));
}
or
function add_things() {
var first = '2';
var second = '4';
alert(Number(first) + Number(second));
}
Note: the second is only really appropriate if you're getting strings from say a property or user input. If they're constants you're defining and you want to add them then define them as integers (as in the first example).
Also, as pointed out, octal is evil. parseInt('010') will actually come out as the number 8 (10 in octal is 8), hence specifying the radix of 10 is a good idea.

Try this:
function add_things() {
var first = 2;
var second = 4;
alert(first + second);
}
Note that I've removed the single quotes; first and second are now integers. In your original, they are strings (text).

That is one of the "Bad Parts" of JavaScript, as a loosely typed language, the addition and concatenation operator is overloaded.
JavaScript is loosely typed, but that doesn't mean that it has no data types just because a value of a variable, object properties, functions or parameters don't need to have a particular type of value assigned to it.
Basically there are three primitive data types:
boolean
number
string
null and undefined are two special cases, everything else are just variations of the object type.
JavaScript type-converts values of types into a type suitable for the context of their use (type coercion).
In your example were trying to add two objects of type string, so a concatenation occur.
You can "cast" or type convert the variables to number in many ways to avoid this problem:
var a = "2";
var b = "4";
// a and b are strings!
var sum = Number(a) + Number(b); // Number constructor.
sum = +a + +b; // Unary plus.
sum = parseInt(a, 10) + parseInt(b, 10); // parseInt.
sum = parseFloat(a) + parseFloat(b); // parseFloat.
This is I think a very common mistake, for example when reading user input from form elements, the value property of form controls is string, even if the character sequence that it contain represents a number (as in your example).
The "Bad Part" which I talk, is about the dual functionality of the + operator, overloaded to be used for both, numeric addition and string concatenation.
The operation that the + operator will do is determined completely by the context. Only if the both operands are numbers, the + operator perform addition, otherwise it will convert all of its operands to string and do concatenation.

The single quotes cause the values to be treated as characters instead of numbers. '2' + '4' = '24' in the same way that 'snarf' + 'blam' = 'snarfblam'.

You could also force the interpreter to perform arithmetic when dealing with numbers in string forms by multiplying the string by 1 (since multiplication can't be done on a string, it'll convert to a number if it can):
// fun with Javascript...
alert(first * 1 + second * 1);
But it's probably best to go with CMS's suggestion of using Number() to force the conversion, since someone will probably come along later and optimize the expression by removing the 'apparently unnecessary' multiply-by-one operations.

Related

Javascript: "+" sign concatenates instead of giving sum of variables

I am currently creating a site that will help me quickly answer physics questions.
As it happens, the code didn't run as expected, here is the code
if (option == "dv") {
var Vinitial = prompt("What is the Velocity Initial?")
var acceleration = prompt("what is the acceleration?")
var time = prompt("what is the time?")
Vfinal = Vinitial + acceleration * time
displayV.innerHTML = "v= vf= " + Vfinal + "ms" + sup1.sup();
}
Now, let's say Vinitial was 9, acceleration was 2, and time was 3.
When the code runs, instead of getting 15 for "Vfinal", I get 96.
I figured out that it multiplies acceleration and time fine, and then just concatenates the 9 at the beginning, with 6 (the product of 2 * 3).
I have fixed it for now by using
Vfinal = acceleration * time - (-Vinitial)
which avoids using the "+" sign, but I don't want to have to keep doing this. How do I fix it?
you are dealing with strings here, and math operations on strings will mess up. Remember when ever you are doing math operations you have to convert the data into actual numbers and then perform the math.
Use parseInt() more Details here
Your code should change to
Vfinal = parseInt(Vinitial,10) + parseInt(acceleration,10) * parseInt(time,10);
Edit 1: If the numbers are decimal values then use parseFloat() instead
So the code would be
Vfinal = parseFloat(Vinitial) + parseFloat(acceleration) * parseFloat(time);
Object-Oriented JavaScript - Second Edition: As you already know, when you use the plus sign with two numbers, this
is the arithmetic addition operation. However, if you use the plus
sign with strings, this is a string concatenation operation, and it
returns the two strings glued together:
var s1 = "web";
var s2 = "site";
s1 + s2; // website
The dual purpose of the + operator is a source of errors. Therefore,
if you intend to concatenate strings, it's always best to make sure
that all of the operands are strings. The same applies for addition;
if you intend to add numbers, make sure the operands are numbers.
You can use "+" operator with prompt() to convert returned values from string to int
var Vinitial = +prompt("What is the Velocity Initial?");
var acceleration = +prompt("what is the acceleration?");
var time = +prompt("what is the time?");
Explanation:
var a = prompt('Enter a digit');
typeof a; // "string"
typeof +a; // "number"
If you will enter non-digit data +a gives you NaN. typeof NaN is "number" too :)
You will get the same result with parseInt():
var Vinitial = parseInt(prompt("What is the Velocity Initial?"), 10);
var acceleration = parseInt(prompt("what is the acceleration?"), 10);
var time = parseInt(prompt("what is the time?"), 10);
developer.mozilla.org: parseInt(string, radix);
string: The value to parse.
radix: An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the above mentioned string.
Specify 10 for the decimal numeral system commonly used by humans.
Always specify this parameter to eliminate reader confusion and to
guarantee predictable behavior. Different implementations produce
different results when a radix is not specified, usually defaulting
the value to 10.
Epilogue:
Object-Oriented JavaScript - Second Edition: The safest thing to do is to always specify the radix. If you omit the radix, your code
will probably still work in 99 percent of cases (because most often
you parse decimals), but every once in a while it might cause you a
bit of hair loss while debugging some edge cases. For example, imagine
you have a form field that accepts calendar days or months and the
user types 06 or 08.
Epilogue II:
ECMAScript 5 removes the octal literal values and avoids the confusion
with parseInt() and unspecified radix.
The Problem is, Your value has been took it in a form of string .. so convert your value into Int using parseInt(accelaration).. then it will work ..
Vfinal = parseInt(Vinitial) + parseInt(acceleration) * parseInt(time)
//use ParseInt
var a=10,b=10;
var sum=parseInt(a+b);
ex:
parseInt(Vinitial + acceleration) * time

Which is the best way to convert a string to float?

I need sum up two number:
var n1 = "3.1416";
var n2 = "2.05";
// i could do this as follow:
// method 1:
var sum = parseFloat(n1) + parseFloat(n2)
// method 2:
var sum = eval(n1) + eval(n2)
// method 3:
var sum = (n1 * 1) + (n2 * 1)
// method 4:
var sum = Number(n1) + Number(n2)
// method 5:
var sum = +n1 + (+n2)
// method 6:
var sum = (n1-0) + (n2-0)
// method 7:
var sum = (n1/1) + (n2/1)
any others?
Which one of this is a less error prone? Why?
That depends on what you want the result to be if the input is not correct.
One thing is sure, you don't want to use eval. Besides being associated with cross site scripting attacks because it runs the string as code rather than just parsing it, it will also crash the script if the input is not completely valid.
Using * 1 hides the real intention of the code. Multiplying something with one is a useless operation as it doesn't change the value at all, so the goal to have the value converted is hidden in the implicit operation that precedes the multiplication.
What those two do, are covered by the other methods (except crashing), so you never need to use them anyway.
The parseFloat and Number functions clearly convey what you are trying to do, but they differ in how they handle input that may or may not be interpreted as a number. Here are some examples:
input parseFloat Number
"3.14" 3.14 3.14
"3.14x" 3.14 NaN
"x3.14" NaN NaN
"" NaN 0
parseFloat is the best. In case your string begins with "non numbers" values, parseFloat will return NaN which stands for Not a Number so be careful.
parseFloat('1.2foobar'); // this will be (float) 1.2
And this :
parseFloat('foobar1.2'); // this will be NaN
You can see the documentation here and try it yourself
Go with "parseFloat", since it will most clearly convey your intention.

New to Javascript calculations

I'm BRAND new to javascript so this is probably an easy fix I can't figure out.
I'm writing a easy script to calculate age Leapyear, Dog years and plus Five.
var age = prompt ("what's your age?");
var dog = age + 7;
var leapyear = age / 4;
var plusFive = age + 5;
document.write(dog, leapyear, plusFive);
JS isn't calculating age + 7. It's writing the age + 7. So if I write 15 in the age prompt it will print in the browser 157.(15) and (7) Which i understand and know why. but how do I get it to compute the math.
It's actually returning 1573.75155
thanks
Like what everyone's been saying, prompt returns a string so it needs to be converted. There are a number of ways to do this, some of which have already been mentioned:
parseInt('123')
parseFloat('123')
Number('123')
These are probably the most common and depending on context also quite possibly the most clear and intuitive ways of doing it. There are also a couple of very terse and interesting ways of converting strings to numbers, depending on which kind of number you'd like. For instance, to convert a number in a string to a float, you can prefix it with the + operator:
+'1.23'
This can seem really counter intuitive, particularly since 4 + '1.23' will actually return 41.23. So what's going on? Well, the + operator, when used as a unary operator (that is, it only has one operand on the right hand side) will always convert the operand value to a number. Compare these two (try them in a javascript console):
4 + '1.23' // returns 41.23
4 + +'1.23' // returns 5.23; the second + is a unary operator
In contrived examples such as this, it really reads rather badly so you might not want to use this trick everywhere. But in your code, it reads quite well:
var age = +prompt("What's your age?")
var dog = age + 7;
var leapyear = age / 4;
var plusFive = age + 5;
If you understand the workings of the unary plus operator (it really isn't rocket surgery) then you can get some nice terse but quite comprehensible results.
The unary + operator will always convert the value to a Number, i.e. floating point. Now, you might want an integer instead, in which case you can use the bitwise not operator twice, like so:
4 + ~~'1.23' // returns 5; note the double operator
This operator first converts the value to an integer, and then returns the bitwise complement of the value, meaning all the bits are inverted. Using it twice will mean that we get the complement's complement, i.e. the original value but this time as an integer instead of a float.
Hope this was informative!
Right now Javascript handles the input as a string, so age is a string. You're gonna want to convert that to an int using the function parseInt(age).
Official documentation
Also, I'd suggest you read this about types in JS
Use either parseInt(age) or parseFloat(age) depending on whether you want to accept non-integer ages.
Your prompt is returning your number as a string, so when you calculate 15 + 7 it's actually just concatenating "7" on to "15".
You need to convert your string to an number:
var age = prompt ("what's your age?");
age = parseInt(age,10); // Converts to an integer
// parseFloat(age) will allow fractional ages
var dog = age + 7;
var leapyear = age / 4;
var plusFive = age + 5;
document.write(dog, leapyear, plusFive);
the age is going to be treated as string so string plus int result in string you have to convert age to int :
var age= parseInt(prompt("what's your age"));
updated...

Extracting number from a string

What is the best way to get the number from a string.
The string will always start with n and end with any number i.e.:
n1
n2
n3
n10
n100
n1000
n99999
n9999999999999
and so on.
If you can guarantee the string will always look like that, then
num = parseInt(str.substring(1));
If it always starts with a single 'n', just keep it simple:
var number = parseInt(value.replace('n', ''));
Number.of = function (number) {
if (typeof number === "number")
return number;
var number = number + '',
regnum = /(-)?[0-9]+\.?[0-9]*/.exec(number);
return regnum ? (new Function('return ' + regnum[0]))() : 0;
};
Then just run..
Number.of('n12345'); // 12345
Mine is an incredibly careful approach to it, but what will pull a number out of anything.
Number.of('Hel5lo'); // 5
And always returns a number.
Number.of('There is no number here.'); // 0
That may or may not be helpful to you though.
You can use String.prototype.substr[docs] (or substring) and an unary + to convert the string to a number:
var number = +str.substr(1);
I's suggest:
$('dt').each(
function(){
var n = $(this).text().substring(1);
$('<dd />').text(n).insertAfter($(this));
});
JS Fiddle demo.
It doesn't matter, obviously, which elements you choose to use (I opted for dt and dd for the implied relationship between the input and the output). The important part is the substring() function; the value of 1 refers to the starting point of the resulting substring (from the second character, as JavaScript works with zero-based arrays).
Had a second number been passed, in the form substring(1,4) the resulting substring would have started from the second character and ended with the fifth, unless the string on which substring() is working is of a length shorter than the second argument, in which case it's treated as being equal to the length of the string.
Reference:
substring() at the Mozilla Developer Center.

Javascript (+) sign concatenates instead of giving sum of variables

Why when I use this: (assuming i = 1)
divID = "question-" + i+1;
I get question-11 and not question-2?
Use this instead:
var divID = "question-" + (i+1)
It's a fairly common problem and doesn't just happen in JavaScript. The idea is that + can represent both concatenation and addition.
Since the + operator will be handled left-to-right the decisions in your code look like this:
"question-" + i: since "question-" is a string, we'll do concatenation, resulting in "question-1"
"question-1" + 1: since "queston-1" is a string, we'll do concatenation, resulting in "question-11".
With "question-" + (i+1) it's different:
since the (i+1) is in parenthesis, its value must be calculated before the first + can be applied:
i is numeric, 1 is numeric, so we'll do addition, resulting in 2
"question-" + 2: since "question-" is a string, we'll do concatenation, resulting in "question-2".
You may also use this
divID = "question-" + (i*1+1);
to be sure that i is converted to integer.
Use only:
divID = "question-" + parseInt(i) + 1;
When "n" comes from html input field or is declared as string, you need to use explicit conversion.
var n = "1"; //type is string
var frstCol = 5;
lstCol = frstCol + parseInt(n);
If "n" is integer, don't need conversion.
n = 1; //type is int
var frstCol = 5, lstCol = frstCol + n;
Since you are concatenating numbers on to a string, the whole thing is treated as a string. When you want to add numbers together, you either need to do it separately and assign it to a var and use that var, like this:
i = i + 1;
divID = "question-" + i;
Or you need to specify the number addition like this:
divID = "question-" + Number(i+1);
EDIT
I should have added this long ago, but based on the comments, this works as well:
divID = "question-" + (i+1);
divID = "question-" + parseInt(i+1,10);
check it here, it's a JSFiddle
Another alternative could be using:
divID = "question-" + (i - -1);
Subtracting a negative is the same as adding, and a minus cannot be used for concatenation
Edit: Forgot that brackets are still necessary since code is read from left to right.
Add brackets
divID = "question-" + (i+1);
using braces surrounding the numbers will treat as addition instead of concat.
divID = "question-" + (i+1)
The reason you get that is the order of precendence of the operators, and the fact that + is used to both concatenate strings as well as perform numeric addition.
In your case, the concatenation of "question-" and i is happening first giving the string "question=1". Then another string concatenation with "1" giving "question-11".
You just simply need to give the interpreter a hint as to what order of prec endence you want.
divID = "question-" + (i+1);
Joachim Sauer's answer will work in scenarios like this. But there are some instances where adding parentheses won’t help.
For example: You are passing “sum of value of an input element and an integer” as an argument to a function.
arg1 = $("#elemId").val(); // value is treated as string
arg2 = 1;
someFuntion(arg1 + arg2); // and so the values are merged here
someFuntion((arg1 + arg2)); // and here
You can make it work by using Number()
arg1 = Number($("#elemId").val());
arg2 = 1;
someFuntion(arg1 + arg2);
or
arg1 = $("#elemId").val();
arg2 = 1;
someFuntion(Number(arg1) + arg2);
var divID = "question-" + (parseInt(i)+1);
Use this + operator behave as concat that's why it showing 11.
Care must be taken that i is an integer type of variable. In javaScript we don't specify the datatype during declaration of variables, but our initialisation can guarantee that our variable is of a specific datatype.
It is a good practice to initialize variables of declaration:
In case of integers, var num = 0;
In case of strings, var str = "";
Even if your i variable is integer, + operator can perform concatenation instead of addition.
In your problem's case, you have supposed that i = 1, in order to get 2 in addition with 1 try using (i-1+2). Use of ()-parenthesis will not be necessary.
- (minus operator) cannot be misunderstood and you will not get unexpected result/s.
One place the parentheses suggestion fails is if say both numbers are HTML input variables.
Say a and b are variables and one receives their values as follows (I am no HTML expert but my son ran into this and there was no parentheses solution i.e.
HTML inputs were intended numerical values for variables a and b, so say the inputs were 2 and 3.
Following gave string concatenation outputs: a+b displayed 23; +a+b displayed 23; (a)+(b) displayed 23;
From suggestions above we tried successfully : Number(a)+Number(b) displayed 5; parseInt(a) + parseInt(b) displayed 5.
Thanks for the help just an FYI - was very confusing and I his Dad got yelled at 'that is was Blogger.com's fault" - no it's a feature of HTML input default combined with the 'addition' operator, when they occur together, the default left-justified interpretation of all and any input variable is that of a string, and hence the addition operator acts naturally in its dual / parallel role now as a concatenation operator since as you folks explained above it is left-justification type of interpretation protocol in Java and Java script thereafter. Very interesting fact. You folks offered up the solution, I am adding the detail for others who run into this.
Simple as easy ... every input type if not defined in HTML is considered as string. Because of this the Plus "+" operator is concatenating.
Use parseInt(i) than the value of "i" will be casted to Integer.
Than the "+" operator will work like addition.
In your case do this :-
divID = "question-" + parseInt(i)+1;

Categories

Resources