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

2007-04-30 Thread Andreas Schwab
Richard Neill <[EMAIL PROTECTED]> 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.

> But in the octal case, bash (quite correctly, and helpfully)
> prints a warning.

It's not a warning, it's an error (and the whole command containing the
expansion is aborted).

> If bash were to be consistent, then it should display no error message in
> the case of $((3+078));

This is a syntax error, so there is no sensible meaning attached to it.  A
syntax error is something quite different than an undefined behaviour.

Andreas.

-- 
Andreas Schwab, SuSE Labs, [EMAIL PROTECTED]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Bob Proulx
Andreas Schwab wrote:
> Richard Neill <[EMAIL PROTECTED]> 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 40*40 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 "40*40" 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",40*40);'
  -2446744073709551616

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

  ruby -e 'puts (40*40).to_s'
  1600

Bob


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Richard Neill



Bob Proulx wrote:

Andreas Schwab wrote:

Richard Neill <[EMAIL PROTECTED]> 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. 


 8<

[OK - agreed. Thanks for your explanation]



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 "40*40" appears as a completely
different problem than "08".



I thought testing for overflow was quite simple?
Isn't it just a case of looking at the carry-bit, and seeing whether it 
gets set? If so, then the warning message would be a two-line patch to 
the code.


That said, I don't know enough about CPU internals to know what the 
carry-bits do with multiplication.  (Addition/Subtraction overflows just 
change the carry-flag; Integer Division never suffers from overflows).




About the only way for bash to avoid it would be to include a full
arbitrary precision math library to evaluate these expressions itself.


I wasn't suggesting that! We have bc anyway. I was only suggesting that, 
when the CPU detects an overflow, bash could pass on the warning.



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",40*40);'
  -2446744073709551616


Yes... but that's actually the %d doing it. Perl would automatically 
convert to a float. Eg


$ perl -e 'print(40*40);'
1.6e+19



Thanks very much for your explanation.

Best wishes,

Richard








___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Paul Jarc
[EMAIL PROTECTED] (Bob Proulx) wrote:
> 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.

Yes, and those are exactly the cases where a message would be helpful,
to let the user know that the result is not portable, and does not
necessarily indicate what the user thinks it does.

Undefined behavior makes sense for C, since C is essentially a
"portable assembly language".  For a higher-level language, it makes
considerably less sense.  And in any case, it does not require the
implementation to be unhelpful.

> About the only way for bash to avoid it would be to include a full
> arbitrary precision math library to evaluate these expressions
> itself.

It depends on the goal.  If the goal is to produce a mathematically
correct result, then yes.  But if the goal is only to detect overflow
and print a warning, then that can still be done without arbitrary
precision.


paul


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Paul Jarc
Richard Neill <[EMAIL PROTECTED]> wrote:
> I thought testing for overflow was quite simple?
> Isn't it just a case of looking at the carry-bit, and seeing whether it 
> gets set?

That's usually how it's done in assembly.  In C, it's somewhat more
compilcated.  For example:
result=a*b;
if (result/a!=b) { report overflow; }


paul


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Andreas Schwab
[EMAIL PROTECTED] (Paul Jarc) writes:

> Richard Neill <[EMAIL PROTECTED]> wrote:
>> I thought testing for overflow was quite simple?
>> Isn't it just a case of looking at the carry-bit, and seeing whether it 
>> gets set?
>
> That's usually how it's done in assembly.  In C, it's somewhat more
> compilcated.  For example:
> result=a*b;
> if (result/a!=b) { report overflow; }

That won't work, since (signed integer) overflow is undefined in C.  A
compiler is allowed to optimize the condition to false.

Andreas.

-- 
Andreas Schwab, SuSE Labs, [EMAIL PROTECTED]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


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

2007-04-30 Thread Paul Jarc
Andreas Schwab <[EMAIL PROTECTED]> wrote:
> [EMAIL PROTECTED] (Paul Jarc) writes:
>> result=a*b;
>> if (result/a!=b) { report overflow; }
>
> That won't work, since (signed integer) overflow is undefined in C.  A
> compiler is allowed to optimize the condition to false.

Right, operations would have to be performed in unsigned arithmetic
and then adjusted for the proper sign, range chaecking, etc., to get
signed results.


paul


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash