Приглашаем посетить
Фет (fet.lit-info.ru)

[Chapter 2] 2.4 Scalar Operators

PreviousChapter 2
Scalar Data
Next
 

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 the section "Conversion Between Numbers and Strings," later in this chapter.

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
10.2 / 0.3 # 10.2 divided by 0.3, or approximately 34
10 / 3     # always floating point divide, so approximately 3.333333...

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 2 to the power of 3, or 8. (If the result cannot 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 <, <=, ==, >=, >, and !=. These operators 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 in the same way a mathematician does. Although there are infinitely many decimal points in them, the computer only has a limited space to store them (usually 64 bits per number). So, just a few of these infinite real numbers can be exactly represented on the computer - the rest are just close.

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, we are using a single period.) This concatenation 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. For example:

"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 do not merely have to 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 using 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.

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 1 results in an empty (zero-length) string.

2.4.3 Operator Precedence and Associativity

Operator precedence defines how to resolve the ambiguous case in which 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 like you learned in your math class). So if I really want the addition before the multiplication, I can say (2+3)*4, yielding 20. Also, if I wanted to demonstrate that multiplication is performed before addition, I 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. You can resolve this by consulting 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 fact scare you away from reading about them.) Operators also found in C have the same precedence as in C).

[6] Asssuming you recall your high school algebra class. If not, simply use parentheses to improve clarity.


Table 2.3: Associativity and Precedence of Operators

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

<< >> (shift operators)

Nonassociative

Named unary operators (like chomp)

Nonassociative

< > <= >= lt gt le ge (relational operators)

Nonassociative

== != <=> eq ne cmp (equality operators)

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 Table 2.3, 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. 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 you use a string value as an operand for a numeric operator (say, +), Perl automatically converts the string to its equivalent numeric value, as if you had entered it as a decimal floating-point value.[7] Trailing nonnumerics and leading whitespaces are politely and quietly ignored, so "123.45fred" (with a leading space) converts to 123.45 with nary a warning.[8] At the extreme, 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 really always do for safety's sake.

Likewise, if you give a numeric value 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 really have to worry about whether you have a number or a string (most of the time). Perl performs all the conversions for you.


PreviousHomeNext
2.3 StringsBook Index2.5 Scalar Variables