[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

11. Arithmetic Evaluation

The shell can perform integer and floating point arithmetic, either using the builtin let, or via a substitution of the form $((...)). For integers, the shell is usually compiled to use 8-byte precision where this is available, otherwise precision is 4 bytes. This can be tested, for example, by giving the command ‘print - $(( 12345678901 ))’; if the number appears unchanged, the precision is at least 8 bytes. Floating point arithmetic always uses the ‘double’ type with whatever corresponding precision is provided by the compiler and the library.

The let builtin command takes arithmetic expressions as arguments; each is evaluated separately. Since many of the arithmetic operators, as well as spaces, require quoting, an alternative form is provided: for any command which begins with a ‘((’, all the characters until a matching ‘))’ are treated as a quoted expression and arithmetic expansion performed as for an argument of let. More precisely, ‘((...))’ is equivalent to ‘let "..."’. The return status is 0 if the arithmetic value of the expression is non-zero, 1 if it is zero, and 2 if an error occurred.

For example, the following statement

 
(( val = 2 + 1 ))

is equivalent to

 
let "val = 2 + 1"

both assigning the value 3 to the shell variable val and returning a zero status.

Integers can be in bases other than 10. A leading ‘0x’ or ‘0X’ denotes hexadecimal. Integers may also be of the form ‘base#n’, where base is a decimal number between two and thirty-six representing the arithmetic base and n is a number in that base (for example, ‘16#ff’ is 255 in hexadecimal). The base# may also be omitted, in which case base 10 is used. For backwards compatibility the form ‘[base]n’ is also accepted.

It is also possible to specify a base to be used for output in the form ‘[#base]’, for example ‘[#16]’. This is used when outputting arithmetical substitutions or when assigning to scalar parameters, but an explicitly defined integer or floating point parameter will not be affected. If an integer variable is implicitly defined by an arithmetic expression, any base specified in this way will be set as the variable’s output arithmetic base as if the option ‘-i base’ to the typeset builtin had been used. The expression has no precedence and if it occurs more than once in a mathematical expression, the last encountered is used. For clarity it is recommended that it appear at the beginning of an expression. As an example:

 
typeset -i 16 y
print $(( [#8] x = 32, y = 32 ))
print $x $y

outputs first ‘8#40’, the rightmost value in the given output base, and then ‘8#40 16#20’, because y has been explicitly declared to have output base 16, while x (assuming it does not already exist) is implicitly typed by the arithmetic evaluation, where it acquires the output base 8.

If the C_BASES option is set, hexadecimal numbers in the standard C format, for example 0xFF instead of the usual ‘16#FF’. If the option OCTAL_ZEROES is also set (it is not by default), octal numbers will be treated similarly and hence appear as ‘077’ instead of ‘8#77’. This option has no effect on the output of bases other than hexadecimal and octal, and these formats are always understood on input.

When an output base is specified using the ‘[#base]’ syntax, an appropriate base prefix will be output if necessary, so that the value output is valid syntax for input. If the # is doubled, for example ‘[##16]’, then no base prefix is output.

Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character e or E may not, as it will be taken for a parameter name.

An arithmetic expression uses nearly the same syntax and associativity of expressions as in C.

In the native mode of operation, the following operators are supported (listed in decreasing order of precedence):

+ - ! ~ ++ –

unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement

<< >>

bitwise shift left, right

&

bitwise AND

^

bitwise XOR

|

bitwise OR

**

exponentiation

* / %

multiplication, division, modulus (remainder)

+ -

addition, subtraction

< > <= >=

comparison

== !=

equality and inequality

&&

logical AND

|| ^^

logical OR, XOR

? :

ternary operator

= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=

assignment

,

comma operator

The operators ‘&&’, ‘||’, ‘&&=’, and ‘||=’ are short-circuiting, and only one of the latter two t>

e output if necessary, so that the value output is valid syntax for input. If the # is doubled, for example ‘[##16]’, then no base prefix is output.

Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character e or E may not, as it will be taken for a parameter name.

An arithmetic expression uses nearly the same syntax and associativity of expressions as in C.

In the native mode of operation, the following operators are supported (listed in decreasing order of precedence):

+ - ! ~ ++ –

unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement

<< >>

bitwise shift left, right

&

bitwise AND

^

bitwise XOR

|

bitwise OR

**

exponentiation

* / %

multiplication, division, modulus (remainder)

+ -

addition, subtraction

< > <= >=

comparison

== !=

equality and inequality

&&

logical AND

|| ^^

logical OR, XOR

? :

ternary operator

= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=

assignment

,

comma operator

The operators ‘&&’, ‘||’, ‘&&=’, and ‘||=’ are short-circuiting, and only one of the latter two t>

e output if necessary, so that the value output is valid syntax for input. If the # is doubled, for example ‘[##16]’, then no base prefix is output.

Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character e or E may not, as it will be taken for a parameter name.

An arithmetic expression uses nearly the same syntax and associativity of expressions as in C.

In the native mode of operation, the following operators are supported (listed in decreasing order of precedence):

+ - ! ~ ++ –

unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement

<< >>

bitwise shift left, right

&

bitwise AND

^

bitwise XOR

|

bitwise OR

**

exponentiation

* / %

multiplication, division, modulus (remainder)

+ -

addition, subtraction

< > <= >=

comparison

== !=

equality and inequality

&&

logical AND

|| ^^

logical OR, XOR

? :

ternary operator

= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=

assignment

,

comma operator

The operators ‘&&’, ‘||’, ‘&&=’, and ‘||=’ are short-circuiting, and only one of the latter two t>

e output if necessary, so that the value output is valid syntax for input. If the # is doubled, for example ‘[##16]’, then no base prefix is output.

Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character e or E may not, as it will be taken for a parameter name.

An arithmetic expression uses nearly the same syntax and associativity of expressions as in C.

In the native mode of operation, the following operators are supported (listed in decreasing order of precedence):

+ - ! ~ ++ –

unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement

<< >>

bitwise shift left, right

&

bitwise AND

^

bitwise XOR

|

bitwise OR

**

exponentiation

* / %

multiplication, division, modulus (remainder)

+ -

addition, subtraction

< > <= >=

comparison

== !=

equality and inequality

&&

logical AND

|| ^^

logical OR, XOR

? :

ternary operator

= += -= *= /= %= &= ^= |= <<= >>= &&= ||= ^^= **=

assignment

,

comma operator

The operators ‘&&’, ‘||’, ‘&&=’, and ‘||=’ are short-circuiting, and only one of the latter two t>

e output if necessary, so that the value output is valid syntax for input. If the # is doubled, for example ‘[##16]’, then no base prefix is output.

Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character e or E may not, as it will be taken for a parameter name.

An arithmetic expression uses nearly the same syntax and associativity of expressions as in C.

In the native mode of operation, the following operators are supported (listed in decreasing order of precedence):

+ - ! ~ ++ –

unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement

<< >>

bitwise shift left, right

&

bitwise AND

^

bitwise XOR

|

bitwise OR