LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   problem with bash calculation (https://www.linuxquestions.org/questions/linux-newbie-8/problem-with-bash-calculation-938399/)

dileepmani 04-05-2012 10:22 PM

problem with bash calculation
 
why is
echo $((1111111111111111111111111%10))
=3
and not 1

I was writing a blog on Fibonacci series ( http://dileepmani19.blogspot.in/2012...i-numbers.html ) and above problem was only solved by
echo "1111111111111111111111111%10" | bc
=1

Dark_Helmet 04-05-2012 11:04 PM

There are limits to the values that can be used in bash--as with every other program.

The bash man page states:
Code:

ARITHMETIC EVALUATION
      The  shell allows arithmetic expressions to be evaluated, under certain
      circumstances (see the let and declare builtin commands and  Arithmetic
      Expansion).  Evaluation  is done in fixed-width integers with no check
      for overflow
, though division by 0 is trapped and flagged as an  error.

I did not see a reference to the exact size of integer bash supports.

However, integers are typically 32 or 64 bits wide. In either case, your string of ones exceeds the value capable of being represented by either. The maximum value a 64-bit integer can represent (without being concerned with negative values) is 18,446,744,073,709,551,615.

For comparison:
Code:

your string of ones:            1,111,111,111,111,111,111,111,111
maximum unsigned 64-bit integer:        18,446,744,073,709,551,615

Your value very likely exceeds the maximum value bash is capable of handling, bash does not signal an "overflow" when you try to use it (as mentioned in the man page above), and so, the number of bits needed to represent your value that exceed bash's internal storage are stripped/dropped/truncated. Your script would be left with a number completely different than you would expect.

The bc program likely uses extra code and/or larger data sizes that can accommodate your value.

Note: the maximum value I showed for a 64-bit integer above is for an unsigned integer. For an integer that can represent both positive and negative values, the maximum value would be reduced by approximately half.

EDIT:
After further research and experimentation, on my machine, the maximum range of integer values bash can represent (on my machine):
Code:

[-9,223,372,036,854,775,808  <-->  +9,223,372,036,854,775,807]
Which corresponds to a signed 64-bit integer.

Shell session:
Code:

user@localhost$ limitcheck=9223372036854775807
user@localhost$ echo $limitcheck
9223372036854775807
user@localhost$ let limitcheck=limitcheck+1
user@localhost$ echo $limitcheck
-9223372036854775808


uhelp 04-05-2012 11:34 PM

bash uses long.
It does NOT check for overflows and wraps around starting then with LLONG_MIN.

So if you do let the bash calculate numbers greater than a LONG, it will give wrong results.

In the second case the bash did no calculating at all.
It just gave a string to bc.

dileepmani 04-06-2012 05:13 AM

Thanks a lot. Your explanations are very lucid.

grail 04-06-2012 01:29 PM

Please mark as SOLVED once you have a solution.


All times are GMT -5. The time now is 06:17 AM.