Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
Not even when started with --posix, or with the env var POSIXLY_CORRECT. perhaps bash needs a --really-really-posix flag... 8-/ 2014-02-25 8:44 GMT+01:00 Dennis Davis : > On Tue, 25 Feb 2014, Ingo Schwarze wrote: > > > From: Ingo Schwarze > > To: Fabian Raetz > > Cc: misc@openbsd.org > > Date: Tue, 25 Feb 2014 01:00:49 > > Subject: Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior > or bug? > > ... > > > > 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: > > ... > > Possibly worth muddying the waters slightly by noting the bash > shell on my old i386 box gets the sum right: > > > poulidor $ cat /tmp/t.sh > #!/usr/local/bin/bash > > echo $((2147483647/2)) > echo $((2147483648/2)) > poulidor $ /tmp/t.sh > 1073741823 > 1073741824 > poulidor $ /usr/local/bin/bash --version > GNU bash, version 4.2.42(1)-release (i386-unknown-openbsd5.3) > Copyright (C) 2011 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later < > http://gnu.org/licenses/gpl.html> > > This is free software; you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. > > > Seems like bash is not adhering to the POSIX standard :-) > -- > Dennis Davis > > -- May the most significant bit of your life be positive.
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
> > 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? Indeed. Sometimes you just can't trust decisions set in stone by POSIX. Sometimes they are just plain broken. If an architecture with a strangely-sized "long" showed up, ksh would have to behave differently again. What are you going to do about it? Complain to the masterminds behind POSIX?
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
Hi, pae3 wrote on Tue, Feb 25, 2014 at 04:52:52PM +0400: > on my i386 system: > > $expr 2147483648 + 0 > -2147483648 > $sh -c 'echo $((2147483648 + 0))' > -2147483648 > $bash -c 'echo $((2147483648 + 0))' > 2147483648 > $zsh -c 'echo $((2147483648 + 0))' > 2147483648 > > bug in ksh? No. Assuming you are running on an ILP32 platform (for example, OpenBSD-i386), these are bugs in bash and zsh and should be fixed there, ksh is correct. Yours, Ingo
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On 02/25/2014 15:43, Fabian Raetz wrote: 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 Hi, on my i386 system: $expr 2147483648 + 0 -2147483648 $sh -c 'echo $((2147483648 + 0))' -2147483648 $bash -c 'echo $((2147483648 + 0))' 2147483648 $zsh -c 'echo $((2147483648 + 0))' 2147483648 bug in ksh? Alex
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
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
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On Tue, 25 Feb 2014, Ingo Schwarze wrote: > From: Ingo Schwarze > To: Fabian Raetz > Cc: misc@openbsd.org > Date: Tue, 25 Feb 2014 01:00:49 > Subject: Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug? ... > > 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: ... Possibly worth muddying the waters slightly by noting the bash shell on my old i386 box gets the sum right: poulidor $ cat /tmp/t.sh #!/usr/local/bin/bash echo $((2147483647/2)) echo $((2147483648/2)) poulidor $ /tmp/t.sh 1073741823 1073741824 poulidor $ /usr/local/bin/bash --version GNU bash, version 4.2.42(1)-release (i386-unknown-openbsd5.3) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Seems like bash is not adhering to the POSIX standard :-) -- Dennis Davis
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On Mon, Feb 24, 2014 at 5:00 PM, Ingo Schwarze wrote: ... > 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. ... > 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. Our expr is broken then: on LP64 platforms (amd64, sparc64, mips64, etc) int is only 32bits while long is 64bits. (We have both kinds of platforms: country (ILP32) and western (LP64). ILP32 have 32bit types for int, long, and pointers, while LP64 have 32bit ints and 64bit longs and pointers.) Philip Guenther
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
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
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
It does for /bin/sh, which is why I suggested perl rather than "echo $(($(sysctl -n hw.physmem)/1024/1024))" which will work on 64-bit arch but not 32-bit. On 24 February 2014 23:49:08 GMT+00:00, Alexander Hall wrote: > > >On February 25, 2014 12:27:41 AM CET, Stuart Henderson > wrote: >>On 2014-02-24, Fabian Raetz wrote: >>> Hi misc@, >>> >>> 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? >> >>I don't see this discussed in ksh(1) - it's expr(1), /bin/expr on >>OpenBSD. > >IIRC i386 differs from amd64 (and other arches too). > >/Alexander > >>This uses 32-bit signed integer types, which are limited to 2^31-1, >>above >>which it wraps around. >> >>It may be possible to change this after we're done with release, but >>for >>now here's a quick workaround: >> >>phys_mem_mb=`perl -e "print int($phys_mem_bytes / 1024 / 1024);"`
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On February 25, 2014 12:27:41 AM CET, Stuart Henderson wrote: >On 2014-02-24, Fabian Raetz wrote: >> Hi misc@, >> >> 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? > >I don't see this discussed in ksh(1) - it's expr(1), /bin/expr on >OpenBSD. IIRC i386 differs from amd64 (and other arches too). /Alexander >This uses 32-bit signed integer types, which are limited to 2^31-1, >above >which it wraps around. > >It may be possible to change this after we're done with release, but >for >now here's a quick workaround: > >phys_mem_mb=`perl -e "print int($phys_mem_bytes / 1024 / 1024);"`
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On 2014-02-24, Fabian Raetz wrote: > Hi misc@, > > 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? I don't see this discussed in ksh(1) - it's expr(1), /bin/expr on OpenBSD. This uses 32-bit signed integer types, which are limited to 2^31-1, above which it wraps around. It may be possible to change this after we're done with release, but for now here's a quick workaround: phys_mem_mb=`perl -e "print int($phys_mem_bytes / 1024 / 1024);"`
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On Mon, Feb 24, 2014 at 11:10:44PM +, Fred wrote: > On 02/24/14 22:32, Richard P??ttler wrote: > >On Mon, Feb 24, 2014 at 10:59 PM, Fabian Raetz > >wrote: > >>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 > >>-- > > > >You declared "#!/bin/sh" so you are using the broune shell, not ksh - fyi. > > > > On OpenBSD sh is the same binary as ksh, the notes section of the sh(1) > gives some more detail as does the faq[1]. > > Fred > > [1]http://www.openbsd.org/faq/faq10.html#ksh #!/bin/sh phys_mem_bytes=$(sysctl -n hw.physmem) phys_mem_mb=$(($phys_mem_bytes / 1024 / 1024)) echo $phys_mem_mb -- -=[rpe]=-
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On 02/24/14 22:32, Richard Pöttler wrote: On Mon, Feb 24, 2014 at 10:59 PM, Fabian Raetz wrote: 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 -- You declared "#!/bin/sh" so you are using the broune shell, not ksh - fyi. On OpenBSD sh is the same binary as ksh, the notes section of the sh(1) gives some more detail as does the faq[1]. Fred [1]http://www.openbsd.org/faq/faq10.html#ksh
Re: ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
On Mon, Feb 24, 2014 at 10:59 PM, Fabian Raetz wrote: > 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 > -- You declared "#!/bin/sh" so you are using the broune shell, not ksh - fyi. > so i tried > expr 2147483647 / 2 which returns 1073741824 while > expr 2147483648 / 2 returns -1073741824 This looks like an integer overflow: http://en.wikipedia.org/wiki/Integer_overflow Have you tried to use bc(1)? cheers richi
ksh: expr 2147483648 / 2 = -1073741824 expected behavior or bug?
Hi misc@, 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? Regards, Fabian Raetz