without: printf "%x\n" $((0x8000000000000000>>1)) c000000000000000 with: $ printf "%x\n" $((0x8000000000000000>>1)) 4000000000000000 without, bash behavior is compiler dependent. The default bash behavior should be to support portable scripts. Also signed shift is just not useful from shell scripts. --- 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);