bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bash arithmetic doesn't give error message on wrap.


From: Bob Proulx
Subject: Re: Bash arithmetic doesn't give error message on wrap.
Date: Mon, 30 Apr 2007 09:09:53 -0600
User-agent: Mutt/1.5.9i

Andreas Schwab wrote:
> Richard Neill <address@hidden> writes:
> > Are you sure this isn't comparable? After all, in both cases, the user has
> > submitted something to which bash cannot give a sensible answer. In the
> > integer-overflow case, bash simply returns the wrong answer, with no
> > warning.
> 
> The answer is not really wrong, it's the same you get from the equivalent
> expression when evaluated in C.

Let me phrase this in a different way.  In the case of the syntax
error "08" bash is doing the input text processing and therefore has
complete control and capability to generate an error message.  But
most importantly the program cannot be executed because it the input
is invalid.  It can't get to the execution phase because of the input
error.

In the case of 4000000000*4000000000 bash is effectively sending the
expression to the computer's math processor and reading the result
back.  The program is valid.  The program is being executed.  But
because the underlying math processing in the cpu has an insufficient
number of bits to hold the result an overflows occurs.  The shell has
less control in this case.  The shell itself is not doing the
multiplication.  The shell is relying upon the cpu to execute the code
of the multiplication and to return the result, which it does.  To the
shell everything appears to operate fine.

Avoiding overflow is actually a very difficult problem.  People have
been working with and around overflow issues for years and years.
There is no clear "right" answer.  On some cpus the result is done one
way and on others the result is done a different way.  It is in these
cases where typically POSIX would give up and declare it undefined
behavior.  This is why "4000000000*4000000000" appears as a completely
different problem than "08".

About the only way for bash to avoid it would be to include a full
arbitrary precision math library to evaluate these expressions itself.
But that would slow the shell down by a large amount and it would make
the shell much bigger than it is today.  Both of those things would
cause people problems.  The entire reason cpus have math processors is
because these operations can be quite slow when done in software.

To give some additional weight to this, note that perl also uses the
underlying cpu for numerical computations.  So this is the same issue
as would be true in Perl.  Or in C/C++ too.

  perl -e 'printf("%d\n",4000000000*4000000000);'
  -2446744073709551616

However a counter point is that Ruby does include an arbitrary
precision math library.

  ruby -e 'puts (4000000000*4000000000).to_s'
  16000000000000000000

Bob




reply via email to

[Prev in Thread] Current Thread [Next in Thread]