Learning Perl

Learning PerlSearch this book
Previous: 2.3 StringsChapter 2
Scalar Data
Next: 2.5 Scalar Variables
 

2.4 Scalar Operators

An operator produces a new value (the result) from one or more other values (the operands). For example, + is an operator because it takes two numbers (the operands, like 5 and 6), and produces a new value (11, the result).

Perl's operators and expressions are generally a superset of those provided in most other ALGOL/Pascal-like programming languages, such as C or Java. An operator expects either numeric or string operands (or possibly a combination of both). If you provide a string operand where a number is expected, or vice versa, Perl automatically converts the operand using fairly intuitive rules, which will be detailed in Section 2.4.4, "Conversion Between Numbers and Strings," below.

2.4.1 Operators for Numbers

Perl provides the typical ordinary addition, subtraction, multiplication, and division operators, and so on. For example:

2 + 3     # 2 plus 3, or 5
5.1 - 2.4 # 5.1 minus 2.4, or approximately 2.7
3 * 12    # 3 times 12 = 36
14 / 2    # 14 divided by 2, or 7
10.2 / 0.3 # 10.2 divided by 0.3, or approximately 34
10 / 3    # always floating point divide, so approximately 3.3333333...

Additionally, Perl provides the FORTRAN-like exponentiation operator, which many have yearned for in Pascal and C. The operator is represented by the double asterisk, such as 2**3, which is two to the third power, or eight. (If the result can't fit into a double-precision floating-point number, such as a negative number to a noninteger exponent, or a large number to a large exponent, you'll get a fatal error.)

Perl also supports a modulus operator. The value of the expression 10 % 3 is the remainder when 10 is divided by 3, which is 1. Both values are first reduced to their integer values, so 10.5 % 3.2 is computed as 10 % 3.

The logical comparison operators are < <= == >= > !=, these compare two values numerically, returning a true or false value. For example, 3 > 2 returns true because three is greater than two, while 5 != 5 returns false because it's not true that 5 is not equal to 5. The definitions of true and false are covered later, but for now, think of the return values as one for true, and zero for false. (These operators are revisited in Table 2.2.)

You may be wondering about the word "approximately" in the code comments at the start of this section. Don't you get exactly 2.7 when subtracting 2.4 from 5.1? In math class you do, but on computers you usually don't. Instead, you get an approximation that's only accurate to a certain number of decimal places. Computers don't store numbers the same way a mathematician thinks of them. But unless you are doing something extreme, you'll usually see the results you expect to see.

Comparing the following statements, you'll see what the computer really got as the result of the subtraction (the printf function is described in Chapter 6, Basic I/O):

printf("%.51f\n", 5.1 - 2.4)
# 2.699999999999999733546474089962430298328399658203125

print(5.1 - 2.4, "\n");
# 2.7

Don't worry too much about this: the print function's default format for printing floating-point numbers usually hides such minor representational inaccuracies. If this ends up being a problem, the Math::BigInt and Math::BigFloat object modules provide infinite-precision arithmetic for integers and floating-point numbers at the cost of somewhat slower execution. For details, see Chapter 7 of Programming Perl or the online documentation on these modules.

2.4.2 Operators for Strings

String values can be concatenated with the "." operator. (Yes, that's a single period.) This does not alter either string, any more than 2+3 alters either 2 or 3. The resulting (longer) string is then available for further computation or to be stored into a variable.

"hello" . "world"       # same as "helloworld"
'hello world' . "\n"    # same as "hello world\n"
"fred" . " " . "barney" # same as "fred barney"

Note that the concatenation must be explicitly called for with the "." operator. You can't just stick the two values close to each other.

Another set of operators for strings are the string comparison operators. These operators are FORTRAN-like, as in lt for less-than, and so on. The operators compare the ASCII values of the characters of the strings in the usual fashion. The complete set of comparison operators (for both numbers and strings) is given in Table 2.2.


Table 2.2: Numeric and String Comparison Operators

Comparison

Numeric

String

Equal

==

eq

Not equal

!=

ne

Less than

<

lt

Greater than

>

gt

Less than or equal to

<=

le

Greater than or equal to

>=

ge

You may wonder why there are separate operators for numbers and strings, if numbers and strings are automatically converted back and forth. Consider the two values 7 and 30. If compared as numbers, 7 is obviously less than 30, but if compared as strings, the string "30" comes before the string "7" (because the ASCII value for 3 is less than the value for 7), and hence is less. Perl always requires you to specify the proper type of comparison, whether it be numeric or string.

Note that if you come from a UNIX shell programming background, the numeric and string comparisons are roughly opposite of what they are for the UNIX test command, which uses -eq for numeric comparison and = for string comparison.

Still another string operator is the string repetition operator, consisting of the single lowercase letter x. This operator takes its left operand (a string), and makes as many concatenated copies of that string as indicated by its right operand (a number). For example:

"fred" x 3       # is "fredfredfred"
"barney" x (4+1) # is "barney" x 5, or 
                 # "barneybarneybarneybarneybarney"
(3+2) x 4        # is 5 x 4, or really "5" x 4, which is "5555"

That last example is worth spelling out slowly. The parentheses on (3+2) force this part of the expression to be evaluated first, yielding five. (The parentheses here are working as in standard math.) But the string repetition operator wants a string for a left operand, so the number 5 is converted to the string "5" (using rules described in detail later), a one-character string. This new string is then copied four times, yielding the four-character string 5555. If we had reversed the order of the operands, we would have made five copies of the string 4, yielding 44444. This shows that string repetition is not commutative.

If necessary, the copy count (the right operand) is first truncated to an integer value (4.8 becomes 4) before being used. A copy count of less than one results in an empty (zero-length) string.

2.4.3 Operator Precedence and Associativity

Operator precedence defines how to resolve the ambiguous case where two operators are trying to operate on three operands. For example, in the expression 2+3*4, do we perform the addition first or the multiplication first? If we did the addition first, we'd get 5*4, or 20. But if we did the multiplication first (as we were taught in math class) we'd get 2+12, or 14. Fortunately, Perl chooses the common mathematical definition, performing the multiplication first. Because of this, we say multiplication has a higher precedence than addition.

You can override the order defined by precedence using parentheses. Anything in parentheses is completely computed before the operator outside of the parentheses is applied (just as you learned in math class). So if you really want the addition before the multiplication, you can say (2+3)*4, yielding 20. Also, if you want to demonstrate that multiplication is performed before addition, you could add a decorative but functionless set of parentheses in 2+(3*4).

While precedence is intuitive for addition and multiplication,[6] we start running into problems when faced with, say, string concatenation compared with exponentiation. The proper way to resolve this is to consult the official, accept-no-substitutes Perl operator precedence chart, shown in Table 2.3. (Note that some of the operators have not yet been described, and in fact, may not even appear anywhere in this book, but don't let that scare you from reading about them.) Operators that are also found in C have the same precedence as in C.

[6] You recall your high-school algebra class? If not, there's nothing wrong with using parentheses to improve clarity.


Table 2.3: Associativity and Precedence of Operators: Highest to Lowest

Associativity

Operator

Left

The "list" operators (leftward)

Left

-> (method call, dereference)

Nonassociative

++ -- (autoincrement, autodecrement)

Right

** (exponentiation)

Right

! ~ \ + - (logical not, bit-not, reference operator, unary plus, unary minus)

Left

=~ !~ (matches, doesn't match)

Left

* / % x (multiply, divide, modulus, string replicate)

Left

+ - . (add, subtract, string concatenate)

Left

<< >>

Nonassociative

Named unary operators (like chomp)

Nonassociative

< > <= >= lt gt le ge

Nonassociative

== != <=> eq ne cmp

Left

& (bit-and)

Left

| ^ (bit-or, bit-xor)

Left

&& (logical and)

Left

|| (logical or)

Nonassociative

.. ... (noninclusive and inclusive range)

Right

?: (if-then-else)

Right

= += -= *=, etc. (assignment and binary-assignment)

Left

, => (comma and comma-arrow)

Nonassociative

List operators (rightward)

Right

not (logical not)

Left

and (logical and)

Left

or xor (logical or, logical xor)

In the chart, any given operator has higher precedence than those listed below it, and lower precedence than all of the operators listed above it.

Operators at the same precedence level resolve according to rules of associativity instead. Just like precedence, associativity resolves the order of operations when two operators of the same precedence compete for three operands:

2 ** 3 ** 4  # 2 ** (3 ** 4), or 2 ** 81, or approx 2.41e24
72 / 12 / 3  # (72 / 12) / 3, or 6/3, or 2
30 / 6 * 3   # (30/6)*3, or 15

In the first case, the ** operator has right associativity, so the parentheses are implied on the right. Comparatively, the * and / operators have left associativity, yielding a set of implied parentheses on the left.

2.4.4 Conversion Between Numbers and Strings

If a string value is used as an operand for a numeric operator (say, +), Perl automatically converts the string to its equivalent numeric value, as if it had been entered as a decimal floating-point value.[7] Trailing nonnumerics and leading whitespace are politely and quietly ignored, so " 123.45fred" (with a leading space) converts to 123.45 with nary a warning.[8] At the extreme end of this, something that isn't a number at all converts to zero without warning (such as the string fred used as a number).

[7] Hex and octal values are not supported in this automatic conversion. Use hex and oct to interpret hex and octal values.

[8] Unless you turn on the -w option from the command line, which you should always do for safety's sake.

Likewise, if a numeric value is given when a string value is needed (for the string concatenate operator, for example), the numeric value is expanded into whatever string would have been printed for that number. For example, if you want to concatenate an X followed by the results of 4 multiplied by 5, you can say this simply as:

"X" . (4 * 5) # same as "X" . 20, or "X20"

(Remember that the parentheses force 4*5 to be computed first, before considering the string concatenation operator.)

In other words, you don't have to worry about whether you have a number or a string (most of the time). Perl performs all the conversions for you.


Previous: 2.3 StringsLearning PerlNext: 2.5 Scalar Variables
2.3 StringsBook Index2.5 Scalar Variables