What is the maximum value of a numeric bash shell variable?

17

5

I'm curious as to what happens when a numeric variable in bash is incremented up without purposely stopping it. How large can the number get? Will it overflow and become negative and just continue to increment forever? Will it break and skid to a stop at some point?

I am using an x86_64 AMD processor, but I would be happy to hear 32bit answers as well, just specify which you are talking about. I am running Fedora21 64bit.

I've googled far and wide but haven't found this specific tidbit for some odd reason. It seems like it would be a basic piece of info in all the manuals and such.

Max Power

Posted 2016-01-22T21:05:37.043

Reputation: 303

3How about printing out some powers of 2 as a starter: for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done – mpy – 2016-01-22T21:19:46.803

1If you want big numbers, you might switch to ksh which does floating point arithmetics, not integer one like bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307 – jlliagre – 2016-01-22T21:36:53.377

I will keep ksh in mind if I need floating point or values in the stratosphere, floating point can be quite useful. But this question is simply so that I know the limits of my system, it is not because I need to exceed its limits. I will do something like mpy suggests, I didn't to start with because I didn't want risk causing a system crash. – Max Power – 2016-01-23T00:27:48.863

Answers

22

It may come down to your version of bash, your OS, and your CPU architecture. Why don't you try it yourself? Set a variable to (2^31)-1, then increment it, set it to 2^32, then increment it, set it to 2^64, then increment it, etc.

Here, I just tried it myself on my Core i7 Mac running OS X "El Capitan" v10.11.3, and it looks like bash is using signed 64-bit integers.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64
$ bash --version
bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
$
$ ((X=2**16)); echo $X
65536                        <-- okay, at least UInt16
$ ((X=2**32)); echo $X
4294967296                   <-- okay, at least UInt32
$ ((X=2**64)); echo $X
0                            <-- oops, not UInt64
$ ((X=(2**63)-1)); echo $X
9223372036854775807          <-- okay, at least SInt64
$ ((X++)); echo $X
-9223372036854775808         <-- overflowed and wrapped negative. Must be SInt64

Spiff

Posted 2016-01-22T21:05:37.043

Reputation: 84 656

3

I set up a loop. while return status is 0 increment a variable with addition and print the variable to stdout I started it just under 2^31, I let it pass both 2^31 and 2^32 with no issue, stopped it, then set the initial value to just under 2^63. The result was that it seamlessly rolled over from 9.22e18 to -9.22e18 and continued to increment positively. (toward zero)

Just to check that my while [ $? -eq 0 ] was actually using the exit status of the commands within the while loop, not using the exit status of the previous script or some oddity, I also ran it with an extra command inside the loop designed to create a non zero exit status at particular increments.

So it is signed, it will roll over rather than stop at max value, and it does so without any error message. So it is possible to end up in a truly infinite loop. It does not limit the 64bit hardware and 64bit linux OS to an old 16 or 32bit standard.

Max Power

Posted 2016-01-22T21:05:37.043

Reputation: 303

2

bash use 64-bit integer. So if you increase after variable reaching its max number, variable will overflow. Below is my test with unsigned int and signed integer.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1

PT Huynh

Posted 2016-01-22T21:05:37.043

Reputation: 151

2please add some text explaining how this answers the question. It looks like you are trying to demonstrate the upper limits via code - can you explain why this code will achieve the required outcome? – Sir Adelaide – 2018-07-13T06:15:22.217