loading...

JavaScript – Arithmetic Expressions

This section covers the operators that perform arithmetic or
other numerical manipulations on their operands. The multiplication,
division, and subtraction operators are straightforward and are
covered first. The addition operator gets a subsection of its own
because it can also perform string concatenation and has some unusual
type conversion rules. The unary operators and the bitwise operators
are also covered in subsections of their own.

The basic arithmetic operators are * (multiplication), / (division), % (modulo: remainder after division),
+ (addition), and - (subtraction). As noted, we’ll discuss the
+ operator in a section of its own.
The other basic four operators simply evaluate their operands, convert
the values to numbers if necessary, and then compute the product,
quotient, remainder, or difference between the values. Non-numeric
operands that cannot convert to numbers convert to the NaN value. If either operand is (or converts
to) NaN, the result of the
operation is also NaN.

The / operator divides its
first operand by its second. If you are used to programming languages
that distinguish between integer and floating-point numbers, you might
expect to get an integer result when you divide one integer by
another. In JavaScript, however, all numbers are floating-point, so
all division operations have floating-point results: 5/2 evaluates to 2.5, not 2. Division by zero yields positive or
negative infinity, while 0/0
evaluates to NaN: neither of these
cases raises an error.

The % operator computes the
first operand modulo the second operand. In other words, it returns
the remainder after whole-number division of the first operand by the
second operand. The sign of the result is the same as the sign of the
first operand. For example, 5 % 2
evaluates to 1 and -5 % 2 evaluates to -1.

While the modulo operator is typically used with integer
operands, it also works for floating-point values. For example,
6.5 % 2.1 evaluates to 0.2.

The + Operator

The binary + operator adds
numeric operands or concatenates string operands:

1 + 2                        // => 3
"hello" + " " + "there"      // => "hello there"
"1" + "2"                    // => "12"

When the values of both operands are numbers, or are both
strings, then it is obvious what the + operator does. In any other case,
however, type conversion is necessary, and the operation to be
performed depends on the conversion performed. The conversions rules
for + give priority to string
concatenation: if either of the operands is a string or an object
that converts to a string, the other operand is converted to a
string and concatenation is performed. Addition is performed only if
neither operand is string-like.

Technically, the + operator
behaves like this:

  • If either of its operand values is an object, it converts
    it to a primitive using the object-to-primitive algorithm
    described in Object to Primitive Conversions: Date objects are
    converted by their toString()
    method, and all other objects are converted via valueOf(), if that method returns a
    primitive value. Most objects do not have a useful valueOf() method, however, so they are
    converted via toString() as
    well.

  • After object-to-primitive conversion, if either operand is
    a string, the other is converted to a string and concatenation
    is performed.

  • Otherwise, both operands are converted to numbers (or to
    NaN) and addition is
    performed.

Here are some examples:

1 + 2         // => 3: addition
"1" + "2"     // => "12": concatenation
"1" + 2       // => "12": concatenation after number-to-string
1 + {}        // => "1[object Object]": concatenation after object-to-string
true + true   // => 2: addition after boolean-to-number
2 + null      // => 2: addition after null converts to 0
2 + undefined // => NaN: addition after undefined converts to NaN

Finally, it is important to note that when the + operator is used with strings and
numbers, it may not be associative. That is, the result may depend
on the order in which operations are performed. For example:

1 + 2 + " blind mice";    // => "3 blind mice"
1 + (2 + " blind mice");  // => "12 blind mice"

The first line has no parentheses, and the + operator has left-to-right
associativity, so the two numbers are added first, and their sum is
concatenated with the string. In the second line, parentheses alter
this order of operations: the number 2 is concatenated with the
string to produce a new string. Then the number 1 is concatenated
with the new string to produce the final result.

Unary Arithmetic Operators

Unary operators modify the value of a single operand to
produce a new value. In JavaScript, the unary operators all have
high precedence and are all right-associative. The arithmetic unary
operators described in this section ( +, -,
++, and --) all convert their single operand to a
number, if necessary. Note that the punctuation characters + and
- are used as both unary
and binary operators.

The unary arithmetic operators are the following:

Unary plus ( +)

The unary plus operator converts its operand to a number
(or to NaN) and returns
that converted value. When used with an operand that is
already a number, it doesn’t do anything.

Unary minus ( -)

When - is used as a
unary operator, it converts its operand to a number, if
necessary, and then changes the sign of the result.

Increment ( ++)

The ++ operator
increments (i.e., adds 1 to) its single operand, which must be
an lvalue (a variable, an element of an array, or a property
of an object). The operator converts its operand to a number,
adds 1 to that number, and assigns the incremented value back
into the variable, element, or property.

The return value of the ++ operator depends on its position
relative to the operand. When used before the operand, where
it is known as the pre-increment operator, it increments the
operand and evaluates to the incremented value of that operand. When used after the
operand, where it is known as the post-increment operator, it
increments its operand but evaluates to the
unincremented value of that operand.
Consider the difference between these two lines of
code:

var i = 1, j = ++i;    // i and j are both 2
var i = 1, j = i++;    // i is 2, j is 1

Note that the expression ++x is not always the same as
x=x+1. The ++ operator never performs string
concatenation: it always converts its operand to a number and
increments it. If x is the
string “1”, ++x is the
number 2, but x+1 is the
string “11”.

Also note that, because of JavaScript’s automatic
semicolon insertion, you cannot insert a line break between
the post-increment operator and the operand that precedes it.
If you do so, JavaScript will treat the operand as a complete
statement by itself and insert a semicolon before it.

This operator, in both its pre- and post-increment
forms, is most commonly used to increment a counter that
controls a for loop (for).

Decrement ( --)

The -- operator
expects an lvalue operand. It converts the value of the
operand to a number, subtracts 1, and assigns the decremented
value back to the operand. Like the ++ operator, the return value of
-- depends on its position
relative to the operand. When used before the operand, it
decrements and returns the decremented value. When used after
the operand, it decrements the operand but returns the
undecremented value. When used after its
operand, no line break is allowed between the operand and the
operator.

Bitwise Operators

The bitwise operators perform low-level manipulation of the
bits in the binary representation of numbers. Although they do not
perform traditional arithmetic operations, they are categorized as
arithmetic operators here because they operate on numeric operands and return a numeric value.
These operators are not commonly used in JavaScript programming, and
if you are not familiar with the binary representation of decimal
integers, you can probably skip this section. Four of these
operators perform Boolean algebra on the individual bits of the
operands, behaving as if each bit in each operand were a boolean
value (1=true, 0=false). The other three bitwise operators are used
to shift bits left and right.

The bitwise operators expect integer operands and behave as if
those values were represented as 32-bit integers rather than 64-bit
floating-point values. These operators convert their operands to
numbers, if necessary, and then coerce the numeric values to 32-bit
integers by dropping any fractional part and any bits beyond the
32nd. The shift operators require a right-side operand between 0 and
31. After converting this operand to an unsigned 32-bit integer,
they drop any bits beyond the 5th, which yields a number in the
appropriate range. Surprisingly, NaN, Infinity, and -Infinity all convert to 0 when used as
operands of these bitwise operators.

Bitwise AND ( &)

The & operator
performs a Boolean AND operation on each bit of its integer
arguments. A bit is set in the result only if the
corresponding bit is set in both operands. For example,
0x1234 & 0x00FF
evaluates to 0x0034.

Bitwise OR ( |)

The | operator
performs a Boolean OR operation on each bit of its integer
arguments. A bit is set in the result if the corresponding bit
is set in one or both of the operands. For example, 0x1234 | 0x00FF evaluates to
0x12FF.

Bitwise XOR ( ^)

The ^ operator
performs a Boolean exclusive OR operation on each bit of its
integer arguments. Exclusive OR means that either operand one
is true or operand two is
true, but not both. A bit
is set in this operation’s result if a corresponding bit is
set in one (but not both) of the two operands. For example,
0xFF00 ^ 0xF0F0 evaluates
to 0x0FF0.

Bitwise NOT ( ~)

The ~ operator is a
unary operator that appears before its single integer operand.
It operates by reversing all bits in the operand. Because of
the way signed integers are represented in JavaScript,
applying the ~ operator to
a value is equivalent to changing its sign and subtracting 1.
For example ~0x0F evaluates
to 0xFFFFFFF0, or −16.

Shift left ( <<)

The << operator
moves all bits in its first operand to the left by the number
of places specified in the second operand, which should be an
integer between 0 and 31. For example, in the operation
a << 1, the first bit
(the ones bit) of a becomes
the second bit (the twos bit), the second bit of a becomes the third, etc. A zero is
used for the new first bit, and the value of the 32nd bit is
lost. Shifting a value left by one position is equivalent to
multiplying by 2, shifting two positions is equivalent to
multiplying by 4, and so on. For example, 7 << 2 evaluates to
28.

Shift right with sign ( >>)

The >> operator
moves all bits in its first operand to the right by the number
of places specified in the second operand (an integer between
0 and 31). Bits that are shifted off the right are lost. The
bits filled in on the left depend on the sign bit of the
original operand, in order to preserve the sign of the result.
If the first operand is positive, the result has zeros placed
in the high bits; if the first operand is negative, the result
has ones placed in the high bits. Shifting a value right one
place is equivalent to dividing by 2 (discarding the
remainder), shifting right two places is equivalent to integer
division by 4, and so on. For example, 7 >> 1 evaluates to 3, and
−7 >> 1 evaluates to
−4.

Shift right with zero fill ( >>>)

The >>>
operator is just like the >> operator, except that the
bits shifted in on the left are always zero, regardless of the
sign of the first operand. For example, −1 >> 4 evaluates to −1, but
−1 >>> 4 evaluates
to 0x0FFFFFFF.

Comments are closed.

loading...