On Tue, Feb 25, 2014 at 02:00:49AM +0100, Ingo Schwarze wrote:
> Hi Fabian,
> 
> Fabian Raetz wrote on Mon, Feb 24, 2014 at 10:59:34PM +0100:
> 
> > while calculating my phys. memory (mb) with the 
> > folllowing shellsript i get as a result -424.
> > 
> > sysctl -n hw.physmem returns 3849830400
> > 
> > ------------
> > #!/bin/sh
> > 
> > phys_mem_bytes=`sysctl -n hw.physmem`
> > phys_mem_mb=`expr $phys_mem_bytes / 1024 / 1024`
> > echo $phys_mem_mb
> > ----------
> > 
> > so i tried
> > expr 2147483647 / 2 which returns 1073741824 while
> > expr 2147483648 / 2 returns -1073741824
> > 
> > ksh(1) states that expr does Integer arithmetic.
> > So is this the expected behaviour or a bug?
> 
> How strange, six replies but nobody answered your question...
> 
> The above behaviour is required by POSIX:
> 
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_01_02_01
> 
>   "Integer variables and constants, including the values of operands
>    and option-arguments, used by the standard utilities listed in
>    this volume of POSIX.1-2008 shall be implemented as equivalent
>    to the ISO C standard signed long data type; floating point shall
>    be implemented as equivalent to the ISO C standard double type.
>    Conversions between types shall be as described in the ISO C
>    standard. All variables shall be initialized to zero if they are
>    not otherwise assigned by the input to the application.
> 
>    Arithmetic operators and control flow keywords shall be implemented
>    as equivalent to those in the cited ISO C standard section, as
>    listed in Selected ISO C Standard Operators and Control Flow
>    Keywords."
> 
> So, POSIX *requires* that the output of "expr 2147483648 + 0"
> and "sh -c 'echo $((2147483648 + 0))'" be machine dependent.
> For example, on i386, where "long" is 32 bit, it must be negative,
> but on amd64, where long is 64 bit, it must be positive.
> I guess it was a bad idea to have the standard require such
> weirdness; then again, this isn't exactly the only place
> where POSIX requires, well, weird behaviour.

Hi,

i should have included that i'm running amd64 and 
"expr 2147483648 + 0" returns -2147483647 while
"sh -c 'echo $((2147483648 + 0))'" returns 1073741824 as expected.

This looks like expr is broken as Philip noted.


I'm pretty new to shell programming and the behavior required by POSIX makes no
sense to me at all .... how could i ever trust in expr with unknown numbers?

For now, i will go with the perl based solution suggested by Stuart.

Thanks to all,
Fabian

Reply via email to