|
From: | Richard Neill |
Subject: | Re: Bash arithmetic doesn't give error message on wrap. |
Date: | Mon, 30 Apr 2007 21:06:02 +0100 |
User-agent: | Thunderbird 1.5.0.10 (X11/20070403) |
Bob Proulx wrote:
Andreas Schwab wrote:Richard Neill <rn214@hermes.cam.ac.uk> 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 "4000000000*4000000000" 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",4000000000*4000000000);' -2446744073709551616
Yes... but that's actually the %d doing it. Perl would automatically convert to a float. Eg
$ perl -e 'print(4000000000*4000000000);' 1.6e+19 Thanks very much for your explanation. Best wishes, Richard
[Prev in Thread] | Current Thread | [Next in Thread] |