[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Fwd: [PATCH] arithmetic -> logical shift]
From: |
Pádraig Brady |
Subject: |
[Fwd: [PATCH] arithmetic -> logical shift] |
Date: |
Fri, 17 Oct 2008 00:10:26 +0100 |
User-agent: |
Thunderbird 2.0.0.6 (X11/20071008) |
-------- Original Message --------
Date: Tue, 07 Oct 2008 11:55:51 +0100
From: Pádraig Brady <P@draigBrady.com>
To: Chet Ramey <chet.ramey@case.edu>
CC: thockin@hockin.org
I was just discussing bit shifting with Tim Hockin using shell
arithmetic expansion, and he pointed out that bash and ksh
use arithmetic rather than logical shift for the >> operator.
Now arithmetic shift is not useful on 2's compliment machines,
and moreover it's compiler dependent as to whether arithmetic
or logical shift is done for >>. Therefore to increase usefulness
and decrease ambiguity I suggest applying something like the
attached simple patch.
I know the opengroup spec says to use signed ints,
but I think that is intended to disambiguate input and output,
rather than defining internal operations.
Some sample output from the patched version:
$ printf "%x\n" $((0x8000000000000000>>1))
4000000000000000
$ smax=$((-1>>1)); echo $smax
9223372036854775807
$ echo $((-0x4000000000000000/2)) $((-0x4000000000000000>>1))
-2305843009213693952 6917529027641081856
And corresponding output from unpatched bash:
$ printf "%x\n" $((0x8000000000000000>>1))
c000000000000000
$ smax=$((-1>>1)); echo $smax
-1
$ echo $((-0x4000000000000000/2)) $((-0x4000000000000000>>1))
-2305843009213693952 -2305843009213693952
cheers,
Pádraig.
--- expr.arithmetic_shift.c 2008-10-06 07:35:09.000000000 +0000
+++ expr.c 2008-10-06 07:11:44.000000000 +0000
@@ -452,7 +452,7 @@
lvalue <<= value;
break;
case RSH:
- lvalue >>= value;
+ lvalue = ((uintmax_t)lvalue) >> value;
break;
case BAND:
lvalue &= value;
@@ -703,7 +703,7 @@
if (op == LSH)
val1 = val1 << val2;
else
- val1 = val1 >> val2;
+ val1 = ((uintmax_t)val1) >> val2;
}
return (val1);
- [Fwd: [PATCH] arithmetic -> logical shift],
Pádraig Brady <=