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. Our /bin/ksh uses "long" to store integers, see /usr/src/bin/ksh/table.h and /usr/src/bin/ksh/expr.c, so that seems fine. Our /bin/expr uses "int" to store integer numbers. As long as we have sizeof(int) == sizeof(long) on all architectures (hum... /me isn't a hardware hacker) that's fine as well. It might be a bad idea to "change this after we're done with release"; on first sight, i see nothing here that might need fixing. Well, maybe a CAVEATS entry in some manuals might make sense, since it doesn't appear as if many people are aware of what POSIX requires... Yours, Ingo