logic commands seem redundant

0 views
Skip to first unread message

Pádraig Brady

unread,
Oct 1, 2008, 3:31:58 PM10/1/08
to iotools-devel
all posix shells support $((arithmetic expansion))
So you can do
echo $((1|2))
printf "0x%X" $((1<<5))
echo $((0x2dec))

How about removing the logical commands?

Tim Hockin

unread,
Oct 1, 2008, 3:50:54 PM10/1/08
to iotool...@googlegroups.com
On Wed, Oct 1, 2008 at 12:31 PM, Pádraig Brady <pixe...@gmail.com> wrote:
>
> all posix shells support $((arithmetic expansion))
> So you can do
> echo $((1|2))
> printf "0x%X" $((1<<5))
> echo $((0x2dec))

try this:

$ X=0xf0000000
$ printf "0x%x\n" $((X>>1))
0x78000000

> How about removing the logical commands?

If you can show me how to do an unsigned right shift, I'd be happy to
consider it :) (though it adds almost no cost)

Tim Hockin

unread,
Oct 1, 2008, 3:52:37 PM10/1/08
to iotool...@googlegroups.com
Sorry, foot-in-mouth diseas.

$ X=0x8000000000000000


$ printf "0x%x\n" $((X>>1))

0xc000000000000000

--
You know what I hate about people who criticize you? They criticize
what you say, but they never give you credit for how loud you say it.

-- Stephen Colbert to Bill O'Reilly

Pádraig Brady

unread,
Oct 1, 2008, 4:53:27 PM10/1/08
to iotools-devel
Well the cost it adds is more interfaces for people to learn/maintain.
But you're right in that $((...)) converts $X to signed int before
doing the shift.
This program demonstrates what's going on internally.

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
intmax_t i = ((intmax_t)0x8000000000000000LL)>>1;
intmax_t u = ((uintmax_t)0x8000000000000000LL)>>1;
printf("%jx\n",i);
printf("%jx\n",u);
}

Both bash and ksh do that, and dash only supports
32 bit on my system (long).

The opengroup spec says:

"As an extension, the shell may recognize arithmetic expressions
beyond those listed (signed long).
The shell may use a signed integer type with a rank larger than the
rank of signed long.
The shell may use a real-floating type instead of signed long as long
as it does not affect
the results in cases where there is no overflow."

So that is explicitly restricting to signed, which doesn't seem
that sensible to me. Ah well.

Tim Hockin

unread,
Oct 1, 2008, 5:13:02 PM10/1/08
to iotool...@googlegroups.com
On Wed, Oct 1, 2008 at 1:53 PM, Pádraig Brady <pixe...@gmail.com> wrote:
>
> Well the cost it adds is more interfaces for people to learn/maintain.

In my own scripts I have used both forms. I don't think the cost is
significant enough to eliminate the tools, but yes, they are largely
redundant (not bts and btr equivalent though :)

--

Pádraig Brady

unread,
Oct 2, 2008, 5:53:57 AM10/2/08
to iotools-devel
Some more thoughts on this.

Basically $((0x8000000000000000>>1)) converts 0x80... to signed
and then does an arithmetic shift on it.
http://en.wikipedia.org/wiki/Arithmetic_shift has good info on this.

There it says that arithmetic shifts on 2's complement machines
(read all modern machines) are not useful.
C99 says in fact that it's up to the compiler as to what is done in
this case.
I.E. it's undefined as to what happens.
I can see why gcc does what it does for backwards compat reasons,
but IMHO a new construct in a high level scripting language should not
be specified as to produce undefined results.

I'll be writing a strongly worded letter :)

Tim Hockin

unread,
Oct 2, 2008, 11:14:48 AM10/2/08
to iotool...@googlegroups.com
On Thu, Oct 2, 2008 at 2:53 AM, Pádraig Brady <pixe...@gmail.com> wrote:
>
> Some more thoughts on this.
>
> Basically $((0x8000000000000000>>1)) converts 0x80... to signed
> and then does an arithmetic shift on it.
> http://en.wikipedia.org/wiki/Arithmetic_shift has good info on this.
>
> There it says that arithmetic shifts on 2's complement machines
> (read all modern machines) are not useful.
> C99 says in fact that it's up to the compiler as to what is done in
> this case.
> I.E. it's undefined as to what happens.
> I can see why gcc does what it does for backwards compat reasons,
> but IMHO a new construct in a high level scripting language should not
> be specified as to produce undefined results.
>
> I'll be writing a strongly worded letter :)

More specifically, ever C implementation I know of does sign extension
on unsigned right shift.

-2 = 0xfffffffe

-2 / 2 = -1

-1 0xffffffff

So sign extension is correct arithmetically. I just wish there was a
way to set unsigned mode. But as far as I know, nope.

Reply all
Reply to author
Forward
0 new messages