even tho it was there, in-shell integer arithmetic had a few
issues before ksh86.
pre-ksh86 these had problems --
A. decimal point in a number
$ integer I
$ I=2.2
would error on the assignment, but with ksh86 $I is truncated to 2
(yes "integer" is an builtin alias to typeset -i and ksh courses at the time
instructed to use that over typset)
B. negative numbers
$ integer I
$ I=-2
here pre-86 $I would be assigned a large value like 2147483646
also ksh was not stardard until SVR4 (very late 80s) so it was found
in paths like /usr/add-on/bin/ksh or /usr/exptools/bin/ksh, or not even
there at all, you could not reliably #! ksh scripts
also with ksh86 the double paren ((...)) notation was exactly the same as
"let ..." and were completely optional if the variable was predefined as
an integer, so
$ I=0
$ ((I=I+1))
and
$ integer I
$ I=0
$ I=I+1
are the same.
All internal integers in ksh were C longs (at least 32-bits)
where Bourne shell all vars are strings so you would need to do this --
$ I=`expr $I + 1`
But also at that time expr(1) could NOT deal with negative numbers on input,
they became strings. So
$ expr -9 + 1
is an error with "non-numeric argument", and
$ expr -11 '<' -1
returns 0, a false statement, which are hidden bugs with variables.
expr(1) was also 32-bits, as was test (i.e [ ) which could deal with
negative numbers just fine.
for arbitrarily large numbers you needed use dc(1) or bc(1). but dc(1)
also has a issue with inputing negative numbers as it uses an _ not
a - to denote a negatve number on input, but does use the - on output.
$ I=`echo _9 1 - p | dc`
is how you would do ((I=-9 - 1)) in bourne with dc
which is cumbersome if you have a variable with a neagtive number in it,
and required a "tr - _" first.
however
$ I=`echo -9 - 1 | bc`
worked just fine in bourne.
-Brian
Chet Ramey wrote:
On 6/21/21 5:57 AM, arnold at
skeeve.com wrote:
Arithmetic expansion dates back at least as far
as ksh88.
ksh had the `let' builtin from at least 1983. The ((...)) compound command
was there by ksh-86.
Bash likely picked it up from there.
Sort of, see below.
The original was only integer math and Bash
remains that way (IIRC,
Chet can correct me if I'm wrong). ksh93 added floating point math.
Yes, bash only has integer arithmetic, since it's all POSIX requires.
POSIX would have picked it up from ksh88.
The $((...)) form of arithmetic expansion is something POSIX picked up
from ksh-88, eventually. The early drafts of the standard (through 1003.2
d9, at least), used $[...], but they eventually adopted $((...)) because
ksh-88 had already implemented it, though it's not documented in Bolsky
and Korn.
I put $[...] into bash first (it's still there, though deprecated), then
`let', then $((...)) after POSIX added it, and finally `((' for
compatibility.
Chet