Numbers

Although a scalar is either a number or a string[1], it's useful to look at numbers and strings separately for the moment.  Numbers first, strings in a minute.

All Numbers Use the Same Format Internally

As you'll see in the next few paragraphs, you can specify both integers (whole numbers, like 255 or 2001) and floating-point numbers (real numbers with decimal points, like 3.14159, or 1.35 times 1025).  But internally, Perl computes only with double-precision floating-point values.[2]  This means that there are no integer values internal to Perl; an integer constant in the program is treated as the equivalent floating-point value.[3]  You probably won't notice the conversion (or care much), but you should stop looking for integer operations (as opposed to floating-point operations), because there aren't any.

Floating-Point Literals

A literal is the way a value is represented in the source code of the Perl program as input to the Perl compiler.  A literal is not the result of a calculation or an I/O operation; it's data written directly into the source code.  You could also call this a constant in your program, but we'll use the term literal

Perl's floating-point literals should look familiar to you.  Numbers with and without decimal points are allowed (including an optional plus or minus prefix), as well as tacking on a power-of-10 indicator with E (exponential) notation.  For example:

1.25
255.000
255.0
7.25e45  # 7.25 times 10 to the 45th power (a big number)
-6.5e24  # negative 6.5 times 10 to the 24th (a big negative number)
-12e-24  # negative 12 times 10 to the -24th (a very small negative number)
-1.2E-23 # another way to say that - the E may be uppercase

Integer Literals

Integer literals are also straightforward, as in:

12
15
-2004
3485
61298040283768

That last one is a little hard to read.  Perl allows underscores for clarity within integer literals, so we can write that number like this:

61_298_040_283_768

It's the same value; it merely looks different to us human beings.  You might have thought that commas should be used for this purpose, but commas are already used for a more important purpose in Perl (as we'll see in a forthcoming lesson).

Non-decimal Integer Literals

Like many other programming languages, Perl allows you to specify numbers in other than base 10 (decimal).  Octal (base 8) literals start with a leading 0, hexadecimal (base 16) literals start with a leading 0x, and binary (base 2) literals start with a leading 0b.[4]  The hex digits A through F (or a through f) represent the conventional digit values of ten through fifteen.  For example:

0377		# 377 octal, same as 255 decimal
-0xff		# negative FF hex, same as -255 decimal
0b11111111	# also 255 decimal (available in version 5.6 and later)

Although these values look different to us humans, they're all three the same number to Perl.  It makes no difference to Perl whether you write 0xFF or 255.000, so choose the representation that makes the most sense to you and your maintenance programmer (by which is meant the poor chap who gets stuck trying to figure out what you meant when you wrote your code.  Most often, this poor chap is you, and you can't recall why you did what you did three months ago).

When a non-decimal literal is more than about four characters long, it may be hard to read.  For this reason, starting in version 5.6, Perl allows underscores for clarity within these literals:

0x1377_0b77
0x50_65_72_7C

Numeric 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).

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...

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.[5]

Perl also 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.) [6]

Another set of operators for numbers are the number or logical comparison operators - < <= == >= > !=.  Some of these may be different than you'd use in other languages.  For example, == is used for equality, not a single = sign, because that's used for another purpose in Perl.  And != is used for inequality testing, because <> is used for another purpose in Perl.  And you'll need >= and not => for "greater than or equal to", because the latter is used for another purpose in Perl.  In fact, nearly every sequence of punctuation is used for something in Perl.  These operators are algebraic-like, as in < for less-than, and so on.  The operators compare the numeric values of the digits of the numbers, 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.  The complete set of comparison operators (for both numbers and strings) is given 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 will be described in a later lesson):

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

	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 (available on CPAN) provide infinite-precision arithmetic for intergers and floating-point numbers at the cost of somewhat slower execution.

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.

Next:  Strings

OR

Main Menu for this topic





























[1] Or a reference, but that's an advanced topic.

Return to the page from whence you came






























[2] A "double-precision floating-point value" is whatever the C compiler that compiled Perl used for a double declaration.  While the size may vary from machine to machine, most modern systems use IEEE floating-point formats, which suggests 15 digits of precision and a range of at least 1e-100 to 1e100.

Return to the page from whence you came






























[3] Unless you use "integer mode," but that's not on by default.  In addition, Perl will sometimes use internal intergers in ways that are not visible to the programmer.  That is, the only difference you should generally be able to see is that your program runs faster.  And who could complain about that?

Return to the page from whence you came






























[4] The "leading zero" indicator works only for literals, not for automatic string-to-number conversion.  You can convert a data string that looks like an octal or hex value into a number with oct() or hex().  Although there's no "bin" function for converting binary values, oct() can do that for strings beginning with 0b.

Return to the page from whence you came






























[5] The result of a modulus operator when a negative number (or two) is involved can vary between Perl implementations.  Beware.

Return to the page from whence you came






























[6] You can't normally raise a negative number to a non-integer exponent.  Math geeks know that the result would be a complex number.  To make that possible, you'll need the help of the Math::Complex module.

Return to the page from whence you came