Help complete table: value range for ksh integer arithmethic

185 views
Skip to first unread message

Heiner Steven

unread,
Apr 28, 2002, 12:18:01 PM4/28/02
to
In the thread "Random line from text file with bash" I pointed
out that ksh "integer" variables may have a limited value
range.

I now wonder if this really is true. I wrote a test script
for finding out the "integer" value range, and ran it using
different shells and different operating systems, and the
range for integer variables was at least

-2147483648 ... 2147483647 -> -2^31 .. (2^31)-1

The following table lists the results for some operating
systems and shells, maybe others could help complete
the list (e.g. using the script at the end of this posting):

minimum value Maximum value
Linux (SuSE 7.3, Kernel 2.4, i386)
pdksh (5.2.14) -2147483648 2147483647
ksh93 (M 1993-12-28 m) -2147483648 2147483647
bash (2.05.01) -2147483648 2147483647

Solaris 9/Sparc
ksh (M-11/16/88i) -9223372036854775808 9223372036854775807
ksh93 (M 1993-12-28 m) -2147483648 2147483647
bash (2.05.01) -2147483648 2147483647

I was a little surprised by the Solaris ksh, but, well, it's an
64 bit operating system, and therefore the value range is
from -2^63 to (2^63)-1.

Please try the following script on your system:

-------------------------------------------------------------------------
#! /usr/bin/ksh
# integertest - test value range for integer variables
# Heiner Steven <heiner...@odn.de>
#
# Tested with
# Linux: pdksh, ksh93, bash
# Solaris 9/SPARC: ksh, ksh93, bash

#trap 'exit 1' ERR

# Find an approximation of the largest number fast by exponential
# approximation

typeset -i i=2
typeset -i next=$i+1

while (( $next > $i && $next > 0 ))
do
((i=$next))
((next=$i*2))
done

# Max. value is between $i and $i*2
typeset -i span=$i/2

while (($span >= 1))
do
((next=$i+$span))
if (( $next > $i && $next > 0 ))
then # valid number
i=$next
else # number too large
((span=$span/2))
fi
if (( $next > $i && $next > 0 ))
then # valid number
i=$next
else # number too large
((span=$span/2))
fi
done

echo "max integer value: $i"

# Now do the same for negative values:

i=0
((next=$i-1))

while (( $next < $i && $next < 0 ))
do
((i=$next))
((next=$i*2))
done

# Minimal value is between $i*2 and $i
typeset -i span=$i/2

while (($span >= 1))
do
((next=$i-$span))
if (( $next < $i && $next < 0 ))
then # valid number
i=$next
else # number too large, decrease increment
((span=$span/2))
fi
done

echo "min integer value: $i"
-------------------------------------------------------------------------

Heiner
--
___ _
/ __| |_ _____ _____ _ _ Heiner STEVEN <heiner...@nexgo.de>
\__ \ _/ -_) V / -_) ' \ Shell Script Programmers: visit
|___/\__\___|\_/\___|_||_| http://www.shelldorado.com/

Juergen Salk

unread,
Apr 28, 2002, 6:51:26 PM4/28/02
to
Heiner Steven <heiner...@nexgo.de> wrote:

> while (($span >= 1))
> do
> ((next=$i+$span))
> if (( $next > $i && $next > 0 ))
> then # valid number
> i=$next
> else # number too large
> ((span=$span/2))
> fi
> if (( $next > $i && $next > 0 ))
> then # valid number
> i=$next
> else # number too large
> ((span=$span/2))
> fi
> done

I think this is one if-block to much.

Best regards - Juergen

HoboSong

unread,
Apr 28, 2002, 11:37:27 PM4/28/02
to
In article <3CCC20B9...@nexgo.de>, Heiner Steven wrote:
> minimum value Maximum value
> Linux (SuSE 7.3, Kernel 2.4, i386)
> pdksh (5.2.14) -2147483648 2147483647
> ksh93 (M 1993-12-28 m) -2147483648 2147483647
> bash (2.05.01) -2147483648 2147483647
>
> Solaris 9/Sparc
> ksh (M-11/16/88i) -9223372036854775808 9223372036854775807
> ksh93 (M 1993-12-28 m) -2147483648 2147483647
> bash (2.05.01) -2147483648 2147483647
>
> I was a little surprised by the Solaris ksh, but, well, it's an
> 64 bit operating system, and therefore the value range is
> from -2^63 to (2^63)-1.
>
> Please try the following script on your system:
>

Linux GNU bash, version 2.05.1(1)-release (i586-mandrake-linux-gnu)
----------
max integer value: 2013265918
min integer value: -2147483648

AIX ksh
---------
max integer value: 8646911284551352318
min integer value: -9223372036854775808

--
---------------------------------------------------------------------
| Chris van Ophuijsen | chris*SPAM*vano@yahoo*DOT*com| RLU #195880 |
---------------------------------------------------------------------

David Thompson

unread,
Apr 29, 2002, 1:51:45 AM4/29/02
to
"Heiner Steven" <heiner...@nexgo.de> wrote
[snip]

$ heiner.ksh


max integer value: 2013265918
min integer value: -2147483648

$ uname -a
IRIX64 dublin 6.5 04151556 IP27

--
David Thompson
dat...@yahoo.com


Jon LaBadie

unread,
Apr 29, 2002, 8:44:54 AM4/29/02
to
Heiner Steven wrote:

>
> Solaris 9/Sparc
> ksh (M-11/16/88i) -9223372036854775808 9223372036854775807
> ksh93 (M 1993-12-28 m) -2147483648 2147483647
> bash (2.05.01) -2147483648 2147483647
>
> I was a little surprised by the Solaris ksh, but, well, it's an
> 64 bit operating system, and therefore the value range is
> from -2^63 to (2^63)-1.
>
> Please try the following script on your system:
>

Be surprised further. I ran your script with various shells on my
Intel version of Solaris 8 (definitely 32 bit :))

Here are my results


ksh88i (Sun supplied ksh) -9223372036854775808 8646911284551352318
ksh93d (compiled locally) -1073741824 2013265918
dtksh (reports as ksh93d) -1073741824 2013265918
ksh93k k+ l l+ and m+ -2147483648 2013265918
bash (Sun supplied 2.03.0) -2147483648 2013265918
zsh (Sun supplied 3.0.6) -9223372036854775808 8646911284551352318


Wide ranges for both ksh88i and zsh, though not the same positive
limit you got.

Note also the two ksh93d's. Both show a reduced negative limit.

those who know me have no need of my name

unread,
Apr 29, 2002, 9:05:24 AM4/29/02
to
<3CCC20B9...@nexgo.de> divulged:

>In the thread "Random line from text file with bash" I pointed
>out that ksh "integer" variables may have a limited value
>range.
>
>I now wonder if this really is true. I wrote a test script
>for finding out the "integer" value range, and ran it using
>different shells and different operating systems, and the
>range for integer variables was at least

tru64 5.1 ksh


max integer value: 8646911284551352318
min integer value: -9223372036854775808

tru64 5.1 bash 2.04.0(1)-release
max integer value: 2013265918
min integer value: -1073741824

--
bringing you boring signatures for 17 years

Heiner Steven

unread,
Apr 29, 2002, 5:54:43 PM4/29/02
to
Jon LaBadie wrote:

> Here are my results
> ksh88i (Sun supplied ksh) -9223372036854775808 8646911284551352318
> ksh93d (compiled locally) -1073741824 2013265918
> dtksh (reports as ksh93d) -1073741824 2013265918
> ksh93k k+ l l+ and m+ -2147483648 2013265918
> bash (Sun supplied 2.03.0) -2147483648 2013265918
> zsh (Sun supplied 3.0.6) -9223372036854775808 8646911284551352318
>
> Wide ranges for both ksh88i and zsh, though not the same positive
> limit you got.
>
> Note also the two ksh93d's. Both show a reduced negative limit.

The different results are due to the garbled script I posted ;-/

But it seems, that ksh88 (by Sun) and the zsh use 64 bit integers.

Heiner Steven

unread,
Apr 29, 2002, 6:02:11 PM4/29/02
to
Thanks to all who sent their results of the test script!

As Juergen Salk pointed out, there was a "copy & paste" error
in the script I posted. Additionally, "dtksh" (Solaris) would
calculate a wrong negative number.

A corrected version is appended to this article.

But not to the summary table. To keep it smaller, I just listed
the number of bits (32 or 64) for each implementation.

The (correct) resulting numbers are

for 64 bit integers -2^63 .. (2^63)-1:
-9223372036854775808 ... 9223372036854775807

for 32 bit integers -2^31 ... (2^31)-1:
-2147483648 ... 2147483647

--------------------------------------------------------------------

Shell internal "integer" sizes
------------------------------

Irix64 6.5
ksh 32 bit

Linux 2.4
bash 2.05.0(1)-release 32 bit
bash 2.05.1(1)-release 32 bit
ksh93 (M 1993-12-28 m) 32 bit compiled locally
pdksh (5.2.14) 32 bit
zsh 4.0.2 64 bit


Solaris 8
ksh88i 64 bit
ksh93d 32 bit compiled locally
dtksh (reports as ksh93d) 32 bit
ksh93k k+ l l+ and m+ 32 bit
bash (Sun supplied 2.03.0) 32 bit
zsh (Sun supplied 3.0.6) 64 bit

Solaris 9
ksh M-11/16/88i 64 bit
ksh93 M 1993-12-28 m 32 bit compiled locally
bash 2.05.0(1)-release 32 bit
zsh 3.8.8 64 bit
dtksh M-12/28/93d 32 bit

Tru64 5.1
ksh 64 bit
bash 2.04.0(1)-release 32 bit

thanks to
Juergen Salk <juerge...@gmx.de>
Chris van Ophuijsen <ch...@alice.gnubin.com>
David Thompson <dat...@yahoo.com>
Jon LaBadie <jgc...@comcast.net>
those who know me have no need of my name <not-a-rea...@usa.net>

for helping to complete the list.

--------------------------------------------------------------------

Maybe others can comment on the following:

It seems that

o ksh uses either 32 or 64 bit for integers (compile-time option?)
o zsh always uses 64 bit
o bash always uses 32 bit
o ksh93 always uses 32 bit (probably configurable during compile-time)


This is the corrected version of the "integertest" script:

--------------------------------------------------------------------
#! /usr/bin/ksh
# integertest - test value range for integer variables
# Heiner Steven <heiner...@odn.de>

# @(#) integertest 1.1 02/04/29
#
# Tested with
# Linux: pdksh, ksh93, bash, zsh
# Solaris 9/SPARC: ksh, ksh93, bash, zsh

#trap 'exit 1' ERR

# Find an approximation of the largest number fast by exponential
# approximation

typeset -i i=2
typeset -i next=$i+1

while (( $next > $i && $next > 0 ))
do
((i=$next))
((next=$i*2))
done

# Max. value is between $i and $i*2
typeset -i span=$i/2

while (($span >= 1))
do
((next=$i+$span))
if (( $next > $i && $next > 0 ))
then # valid number
i=$next
else # number too large
((span=$span/2))
fi

done

echo "max integer value: $i"

#########################################################################
# Now repeat the process for negative values
#########################################################################

i=0
((next=$i-1))

while (( $next < $i && $next < 0 ))
do
((i=$next))
((next=$i*2))
done

# Minimal value is between $i*2 and $i
typeset -i span=$i/2

(($span < 0)) && ((span=-1*$span))

while (($span >= 1))
do
((next=$i-$span))
if (( $next < $i && $next < 0 ))
then # valid number
i=$next
else # number too large, decrease increment
((span=$span/2))
fi
done

echo "min integer value: $i"
--------------------------------------------------------------------

Heiner

those who know me have no need of my name

unread,
May 2, 2002, 5:53:42 PM5/2/02
to
here are some more results.

the second group seems to expose a bug in bash. it looks like math is
being done with native (64 bit) ints, and the reduction to standard(?)
value range (32 bit signed) is buggy.

(failed)
bash 1.14.7(1) debian 2.1 (linux 2.4.0) armv4l

max integer value: -2147483648
min integer value: -2147483647
bash 2.01.0(1)-release tru64 4.0g alpha ev5
bash 2.03.0(1)-release tru64 5.1a alpha ev6
bash 2.04.0(1)-release tru64 5.1a alpha ev68
bash 2.05.8(1)-release redhat 7.1 ia64

max integer value: 2147483647
min integer value: -2147483648
bash 2.05.0(1)-release debian 2.1 armv4l
bash 2.05.0(1)-release openbsd 3.0 i386
bash 2.05.0(1)-release redhat 6.2 i686
bash 2.05.0(1)-release sunos 4.1.4 sun4m
ksh M 1993-12-28 m+ debian 2.1 armv4l
ksh M 1993-12-28 m+ openbsd 3.0 i386
pdksh v5.2.7 96/06/04 sunos 4.1.4 sun4m
pdksh v5.2.14 99/07/13.2 openbsd 3.0 i386
zsh 3.0.5 sunos 4.1.4 sun4m

max integer value: 9223372036854775807
min integer value: -9223372036854775808
ksh M-11/16/88f tru64 5.1a alpha ev68
zsh 3.1.9 tru64 5.1a alpha ev6

max integer value: 9223372036854774784
min integer value: -9223372036854775808
ksh M 1993-12-28 m+ redhat 7.1 ia64
ksh M 1993-12-28 m+ tru64 4.0g alpha ev5
ksh M 1993-12-28 m+ tru64 5.1a alpha ev6
ksh M 1993-12-28 m+ tru64 5.1a alpha ev68

laura fairhead

unread,
May 2, 2002, 6:32:33 PM5/2/02
to
On Tue, 30 Apr 2002 00:02:11 +0200, Heiner Steven <heiner...@nexgo.de> wrote:

>Thanks to all who sent their results of the test script!
>
>As Juergen Salk pointed out, there was a "copy & paste" error
>in the script I posted. Additionally, "dtksh" (Solaris) would
>calculate a wrong negative number.
>
>A corrected version is appended to this article.
>
>But not to the summary table. To keep it smaller, I just listed
>the number of bits (32 or 64) for each implementation.
>
>The (correct) resulting numbers are
>
>for 64 bit integers -2^63 .. (2^63)-1:
> -9223372036854775808 ... 9223372036854775807
>
>for 32 bit integers -2^31 ... (2^31)-1:
> -2147483648 ... 2147483647
>
>--------------------------------------------------------------------

More coming....

NetBSD 1.5.3 / Alpha / pdksh v5.2.14 99/07/13.2

max = 9223372036854775807
min = -9223372036854775808

byefrom

--
laura fairhead # la...@madonnaweb.com http://lf.8k.com
# if you are bored crack my sig.
1F8B0808CABB793C0000666667002D8E410E83300C04EF91F2877D00CA138A7A
EAA98F30C494480157B623C4EF1B508FDED1CEFA9152A23DE35D661593C5318E
630C313CD701BE92E390563326EE17A3CA818F5266E4C2461547F1F5267659CA
8EE2092F76C329ED02CA430C5373CC62FF94BAC6210B36D9F9BC4AB53378D978
80F2978A1A6E5D6F5133B67B6113178DC1059526698AFE5C17A5187E7D930492

Richard Howlett

unread,
May 2, 2002, 8:55:12 PM5/2/02
to
Heiner Steven wrote:
>
> In the thread "Random line from text file with bash" I pointed
> out that ksh "integer" variables may have a limited value
> range.

Using your 2nd version of integertest:

SCO Openserver 5.0.5, i386
ksh Version 11/16/88g
GNU bash 2.01.0(3))
and
RedHat Linux 7.0, kernel 2.2.19-7.0.12, i686
ksh PD KSH v5.2.14 99/07/13.2
GNU bash, version 2.04.11(1)

all give same result

max integer value: 2147483647
min integer value: -2147483648

--
Richard Howlett

mailto:ric...@howie.org.uk

parv

unread,
May 3, 2002, 11:14:00 PM5/3/02
to
on freebsd 4.6 prerelease/i386...

bash 2.05 & ksh93...

max integer value: 2147483647
min integer value: -2147483648

zsh 4.0.4...

max integer value: 9223372036854775807
min integer value: -9223372036854775808


--
remove WhereElse to send private email

Reply all
Reply to author
Forward
0 new messages