GNU Info

Info Node: (zsh.info)Arithmetic Evaluation

(zsh.info)Arithmetic Evaluation


Next: Conditional Expressions Prev: Jobs & Signals Up: Top
Enter node , (file) or (file)node

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 is always double precision.

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

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, precedence, and
associativity of expressions in C.  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 expressions in a ternary operator is
evaluated.  Note the precedence of the bitwise AND, OR, and XOR
operators.

Mathematical functions can be called with the syntax `FUNC(ARGS)',
where the function decides if the ARGS is used as a string or a
comma-separated list of arithmetic expressions. The shell currently
defines no mathematical functions by default, but the module
zsh/mathfunc may be loaded with the zmodload builtin to provide
standard floating point mathematical functions.

An expression of the form `##X' where X is any character sequence such
as `a', `^A', or `\M-\C-x' gives the ASCII value of this character and
an expression of the form `#FOO' gives the ASCII value of the first
character of the value of the parameter FOO.  Note that this is
different from the expression `$#FOO', a standard parameter
substitution which gives the length of the parameter FOO.  `#\' is
accepted instead of `##', but its use is deprecated.

Named parameters and subscripted arrays can be referenced by name
within an arithmetic expression without using the parameter expansion
syntax.  For example,

     ((val2 = val1 * 2))

assigns twice the value of $val1 to the parameter named val2.

An internal integer representation of a named parameter can be
specified with the integer builtin.  Arithmetic evaluation is performed
on the value of each assignment to a named parameter declared integer
in this manner.  Assigning a floating point number to an integer
results in rounding down to the next integer.

Likewise, floating point numbers can be declared with the float
builtin; there are two types, differing only in their output format, as
described for the typeset builtin.  The output format can be bypassed
by using arithmetic substitution instead of the parameter substitution,
i.e. `${FLOAT}' uses the defined format, but `$((FLOAT))' uses a
generic floating point format.

Promotion of integer to floating point values is performed where
necessary.  In addition, if any operator which requires an integer
(`~', `&', `|', `^', `%', `<<', `>>' and their equivalents with
assignment) is given a floating point argument, it will be silently
rounded down to the next integer.

Scalar variables can hold integer or floating point values at different
times; there is no memory of the numeric type in this case.

If a variable is first assigned in a numeric context without previously
being declared, it will be implicitly typed as integer or float and
retain that type either until the type is explicitly changed or until
the end of the scope.  This can have unforeseen consequences.  For
example, in the loop

     for (( f = 0; f < 1; f += 0.1 )); do
     # use $f
     done

if f has not already been declared, the first assignment will cause it
to be created as an integer, and consequently the operation `f += 0.1'
will always cause the result to be truncated to zero, so that the loop
will fail.  A simple fix would be to turn the initialization into `f =
0.0'.  It is therefore best to declare numeric variables with explicit
types.


automatically generated by info2www version 1.2.2.9