sr #108381: Bug in the right bitwise shift >>

 Submitter: None Submitted: Sun 01 Sep 2013 03:11:44 PM UTC Category: None Priority: 5 - Normal Severity: 3 - Normal Status: Invalid Privacy: Public Assigned to: None Originator Email: -email is unavailable- Open/Closed: Open Operating System: GNU/Linux
* Mandatory Fields

Add a New Comment Rich Markup

Discussion

Wed 25 Mar 2015 11:00:19 AM UTC, comment #3:

Not a bug.

Eduardo Bustamante <dualbus>
Tue 26 Nov 2013 03:33:14 PM UTC, comment #2:

The bash docs say that ARITHMETIC EVALUATION is done in fixed width integer (not unsigned), so unfortunately the current behaviour is what the manual says.  Logical right shift is not available, only arithmetic right shift.  Also see expr.c, everything is done in intmax_t variables.

See http://en.wikipedia.org/wiki/Arithmetic_shift.

The C standard says E1 >> E2 is equivalent to division by 2^E2 if E1 is unsigned or non-negative.  Otherwise the result is implementation-defined (K&R 2nd edition).  This "implementation defined" language is just to account for the fact that C doesn't specify whether the machine uses the now-universal 2's complement representation for negative integers.  Arithmetic right shift on 2's complement is equivalent to division by a power of 2, but rounding towards -infinity instead of towards zero.

With signed int variables, C compilers will use arithmetic shifts, not logical shift.  I agree it would be more useful to have logical shifts available, since it's pretty rare that you'd want an arithmetic right or left shift and couldn't multiply or divide by a power of 2 instead.  If the speed of integer division vs. shifting is an issue, probably shell scripts aren't the right tool in the first place!

Peter Cordes <pcordes>
Sun 01 Sep 2013 06:06:46 PM UTC, comment #1:

Typo correction: "makes mo sense" should read "makes no sense".

Anonymous
Sun 01 Sep 2013 03:11:44 PM UTC, original submission:

In the current Bash 4.2, the right bitwise shift >> doesn't always fill in with zero bits from the left.  The left bitwise shift << works as expected, allowing bits to shift all the way to the leftmost position.  But once the leftmost bit is flipped, reversing with a right bitwise shift >> doesn't work as expected.

For example, say we want to find the highest signed integer on a particular system. We'd do:
# echo \$(( ( ~ 0 ) >> 1  ))
The above should return 0x7Fff...ff.  Instead, it returns 0xFFff...ff.
On a 64-bit system, we should get 9223372036854775807. Instead, we get -1.

This bug may have come from the concept of "sign bit", which applies if we are talking about arithmetic shifts (like *2 or /2), but makes mo sense if we are doing logical bitwise shilfs.  So, << doesn't know of sign bits (as it's supposed to be), but >> makes the most signifficant bit stick for some reason.  Either << or >> should be fixed to remove this incinsistency.  Preferrably, the >> is the one that needs fixing.

Anonymous

Attached Files

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Comment:

No files currently attached

Dependencies

Depends on the following items: None found

Items that depend on this one: None found

Carbon-Copy List
• -email is unavailable- added by chet (Updated the item)
• -email is unavailable- added by dualbus (Posted a comment)
• -email is unavailable- added by pcordes (Posted a comment)
•

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

Only logged-in users can vote.

History

Follows 1 latest change.

Date Changed by Updated Field Previous Value => Replaced by
2015-11-13 chet StatusNone Invalid