+ operator is concatinating rather adding even after parseFloat method - javascript

In following expression
parseFloat((($scope.Product.cost/100) * $scope.Product.profit) + $scope.Product.cost);
+ operator is concatinating the values and i expect it to perform addition.

...even after parseFloat method
The + part of that expression isn't after the parseFloat, it's before the parseFloat.
You probably wanted:
(($scope.Product.cost/100) * $scope.Product.profit) + parseFloat($scope.Product.cost);
Note that cost in the above is implicitly converted to number when you use it in the /100 expression, but you're explicitly converting it with parseFloat elsewhere. Those two things don't do quite the same thing.
I'd probably prefer to convert, then calculate:
var cost = parseFloat($scope.Product.cost); // or +$scope.Product.cost
var profit = parseFloat($scope.Product.profit); // or +$scope.Product.profit
var result = ((cost/100) * profit) + cost;
See this answer for a rundown of the differences between implicit string-to-number conversion vs. parseFloat (and others).
Side note: You don't need some of the parens you're using, the last line of the convert-then-calculate above could be:
var result = (cost/100) * profit + cost;
...because * has higher precedence than +. But the extra () are harmless.

Convert each of the variables in your expression to number by applying the + unitary operator on each of them:
+$scope.Product.cost/100 * +$scope.Product.profit + +$scope.Product.cost;
As noted in comments, the coercion to float is implied for the first part of the expression by the / and * operators, but not so for the + operator, which will coerce the first numerical result to string unless the second argument is first converted to number as well.
So the first two + unitary operators are not really necessary.

Related

Is it safe to use strings in arithmetic expressions?

I have a number of seconds in a string, like: '5'.
From that I need to get the number of milliseconds and it has to be of type Number, like: 5000.
I know that you can easily convert strings to numbers by prefixing them with a +
const result = +'5';
console.log(result, typeof(result));
However playing around I saw that that's not even necessary because JavaScript automatically does the conversion for you when you try to use arithmetic between strings and numbers.
const result = '5' * 3;
console.log(result, typeof(result));
console.log('5.3' * 3);
On the docs I only found info about the Number() constructor.
My question is: is it safe to use arithmetic on strings (except for the addition)? Can I rely on the behaviour showed above?
Yes, it is safe. All arithmetic operations except a binary + will convert the operands to numbers. That includes bitwise operators as well as unary plus.
With that said, it is probably a good idea not to rely on this extensively. Imagine that you have this code:
function calculate(a, b) {
return a * 2 + b * 3;
}
//elsewhere in the code
console.log(calculate("5", "2"));
This works fine because both a and b are multiplied, so are going to be converted to numbers. But in six months time you come back to the project and realise you want to modify the calculation, so you change the function:
function calculate(a, b) {
return a + b * 3;
}
//elsewhere in the code
console.log(calculate("5", "2"));
...and suddenly the result is wrong.
It is therefore better if you explicitly convert the values to numbers if you want to do arithmetic. Saves the occasional accidental bug and it is more maintainable.
Yes, but you have to be careful...
console.log('5.3' * 3);
console.log('5.3' + 3);
These two very similar functions cast the values different ways:
* can only be applied between two numbers, so '5.3' becomes 5.3
+ can also concatenate strings, and the string comes first, so 3 becomes '3'
If you understand all these you can do this, but I'd recommend against it. It's very easy to miss and JS has a lot of weird unexpected casts.

What does +a + +b mean in JavaScript?

There was an answer to a nested array problem on stack overflow that involved a return statement +a + +b. (no period) What is this? What does it do? It seems to add, but I'm not sure how it does that. How does it differ from a + b? The code is below, and it works:
var array= [1, 2, [3, 4], [], [5]];
var sum = array.toString().split(",").reduce(function(a, b) { return +a + +b;
});
console.log(sum);
The + before the variable is the unary + operator. You are probably familiar with the unary -, e.g. -x.
Both +x and -x convert x to a number, but -x also changes its sign. This is not the primary purpose of the existance of the unary +, but it is a nice sideeffect.
Therefore, the difference between a + b and +a + +b would be visible from this example:
x = '9'; // '9'
x = +'9'; // 9
x = '9' + '9'; // '99'
x = +'9' + +'9'; // 18
JavaScript is dynamically typed, but has no built-in operators for casting a value to ensure it is the right type for an operation. Consequently, various tricks are used when it's important that a value is treated as a number, or a string, etc.
In this case, the operator being used is the "unary +" which is the natural counterpart of the "unary -" that would be used to write a negative number: just as "-x" means "0 - x", "+x" means "0 + x". On a number, this has no effect, but other values will be converted to a number.
This is important because the "binary +" operator does different things depending on the type of its operands: if a was a string, a + b would mean "append two strings together" rather than "sum two numbers".
Given an imaginary cast_to_number function, the equation could be more readably written as return cast_to_number(a) + cast_to_number(b).
Assuming a or b were of type String, adding a + operator in front of it will coerce it to a number.
This ensures that ’1’ + ‘1’ will be 2 (addition of numbers) and not 11 (concatenation of strings).
javascript has a unary operator + and -, both of them converts the operand to a number type, but the - operator negate the result.
for example:
> -'20'
-20
> +'500' + +'600'
1100
The + unary operator is used for explicit coercion in JavaScript.
Even though some developers look down upon it, saying var num = 3 + +c; is rather ugly especially to people not aware of the coercion at hand, potentially even "error-like" looking piece of code.
The most common practical use of the + unary operator is probably to get a number timestamp of the date
var timestamp = +new Date(); // this works!
Perhaps a good piece of memorablia is the - unary operator, which for some reason our human brain seems much happier to interpret. Basically, if we see var x = -c; we presume the compiler:
Attempts to do a value to number coercion of the variable c
If it can return a number, flip the sign and return the negative number (-)
The + unary operator does the same thing, only without the sign flipping.

What does JavaScript interpret `+ +i` as?

An interesting thing I've never seen before was posted in another question. They had something like:
var i = + +1;
They thought the extra + converted it to a string, but they were simply adding to a string which is what caused it to convert.
This, however, lead me to the question: what is going on here?
I would have actually expected that to be a compiler error, but JavaScript (at least in Chrome) is just fine with it... it just basically does nothing.
I created a little JSFiddle to demonstrate: Demo
var i = 5;
var j = + +i;
document.body.innerHTML = i === j ? 'Same' : 'Different';
Anyone know what's actually occurring and what JavaScript is doing with this process?
I thought maybe it would treat it like ++i, but i doesn't increment, and you can even do it with a value (e.g., + +5), which you can't do with ++ (e.g., ++5 is a reference error).
Spacing also doesn't affect it (e.g., + + 1 and + +1 are the same).
My best guess is it's essentially treating them as positive/negative signs and putting them together. It looks like 1 == - -1 and -1 == + -1, but that is just so weird.
Is this just a quirky behavior, or is it documented in a standard somewhere?
Putting your the statement through the AST Explorer, we can see that what we get here is two nested Unary Expressions, with the unary + operator.
It's a unary expression consisting of + and +i, and +i is itself a unary expression consisting of + and i.
The unary expression with the unary + operator, will convert the expression portion into a number. So you're essentially converting i to a number, then converting the result of that to a number, again (which is a no-op).
For the sake of completion, it works on as many levels as you add:
var i = 5;
console.log(+ + + + + +i); // 5
console.log(i); // still 5
It's in the specification.
Digging through, we can see from §14.6.2.2 that the increment and decrement operators are listed before (and should be preferred) over the unary operators. So precedence alone won't explain this.
Looking up the the punctuation table in §11.7, we can see that every single instance of ++ (the operator) in the spec shows the two together, without whitespace. That's not conclusive, until you check...
The whitespace rules in §11.2, specifically:
White space code points may occur within a StringLiteral, a RegularExpressionLiteral, a Template, or a TemplateSubstitutionTail where they are considered significant code points forming part of a literal value. They may also occur within a Comment, but cannot appear within any other kind of token.
JS does not allow arbitrary whitespace mid-operator.
The JS syntax in both PegJS and Esprima corroborate this, matching on the literal two-character string ++.
For me it's very clear;
var a = +3;
var b = +a; // same as a, could be -a, for instance
var c = + +a; // same as above, same as +(+a)
If you do ++variable the javascript interpreter sees it as the increment operator.
If you do + +variable the javascript interpreter sees it as Unary plus, coercing the value to a number, twice.
So
var a = 1;
var b = +a;
var c = +b;
console.log(c);// still 1
is the same as
var c = + +1;
So the simple answer is that two plus signs can not be separated by a space to be interpreted as incrementation, the space makes it so the interpreter sees two seperate spaces, which is what it really is
The + operators converts into a number, two + operators with a space in between does nothing additional.
Even though it might look very similar, + + and ++ are not at all the same thing for an AST interpreter. The same applies to token separation: varfoo is not the same as var foo.
In the expression + + +i, each + is considered as distinct unary operator, which simply convert your variable to a number. For the incrementation operation, which is ++, no spaces are allowed, neither between the + and the variable token. In the example below, the last line is not valid:
var x = "4";
console.log(+ + +x);
console.log(+ + ++x);
console.log(+ ++ +x);

Can someone please explain this JavaScript decimal rounding function in detail?

function Round2DecimalPlaces(l_amt) {
var l_dblRounded = +(Math.round(l_amt + "e+2") + "e-2");
return l_dblRounded;
}
Fiddle: http://jsfiddle.net/1jf3ut3v/
I'm mainly confused on how Math.round works with "e+2" and how addition the "+" sign to the beginning of Math.round makes any difference at all.
I understand the basic of the function; the decimal gets moved n places to the right (as specified by e+2), rounded with this new integer, and then moved back. However, I'm not sure what 'e' is doing in this situation.
eX is a valid part of a Number literal and means *10^X, just like in scientific notation:
> 1e1 // 1 * Math.pow(10, 1)
10
> 1e2 // 1 * Math.pow(10, 2)
100
And because of that, converting a string containing such a character sequence results in a valid number:
> var x = 2;
> Number(x + "e1")
20
> Number(x + "e2")
200
For more information, have a look at the MDN JavaScript Guide.
But of course the way this notation is used in your example is horrible. Converting values back and forth to numbers and strings is already bad enough, but it also makes it more difficult to understand.
Simple multiple or divide by a multiple of 10.
The single plus operator coerces a the string into a float. (See also: Single plus operator in javascript )

why do I get 24 when adding 2 + 4 in 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.

Categories

Resources