Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4495754
Votes 1
Synopsis Add library support for common bit manipulation operations
Category java:classes_lang
Reported Against 1.4 , 1.4.1 , tiger-beta , merlin-beta
Release Fixed 1.5(tiger)
State 10-Fix Delivered, request for enhancement
Priority: 4-Low
Related Bugs 4210457 , 4736393 , 4823675 , 4850191 , 4850194 , 4900166 , 4967876
Submit Date 23-AUG-2001
Description



Java adds the arithmetic shift operator, but roll and count leading zeros would
be very nice intrinsic routines (bytecodes anyone).   These are very important
for bit-twidling, and have fast processor-specific equivalents on most
processors.
(Review ID: 130571) 
======================================================================
Work Around




write functions for these
======================================================================
Evaluation
It certainly is NOT worthy of a byte code. Might be worth a library routine.

  xxxxx@xxxxx   2001-10-23

   We intend to add a fairly complete set of "bit-twiddling" methods to Integer and perhaps Long in the next major release (code-named "Tiger").  In addition to the requested methods, this set might include count one bits (AKA population count), get leading one bit, count trailing zeros and get trailing one bit.  Other suggestions welcome.

  xxxxx@xxxxx   2001-10-23


Byte swapping routines for shorts, ints, and longs would be useful for New I/O
and could be intrinsified down to one or two machine instructions on most
processors we support. Putting such routines in the public API would be
beneficial to customers.

  xxxxx@xxxxx   2003-04-23
Comments
  
  Include a link with my name & email   

Submitted On 01-APR-2002
Ixchel
One suggestion: Numeric constants to indicate things like 
the number of bits in the type (Integer.NUM_BITS would be 
equal to 32, for instance)
Also I would like to see some methods in Integer and Long 
to do bit-masking, such as to perform operations like:

int resetBits(int orig, int bits) {return orig & ~bits;}
int setBits(int orig, int bits) {return orig | bits;}
int resetBits(int orig, int mask, int bits) {return (orig & 
~mask) | bits);}
int setBitAtPos(int orig, int pos) {return orig & (1 >> 
pos);}
int resetBitAtPos(int orig, int pos) {return orig & ~ (1 >> 
pos);}

Yes, some of these method names are nearly as long as the 
operations they replace. However, they are much more self-
documenting, and would reduce errors. Additionally, the 
strongly typed nature of the parameters provides error 
checking. Hopefully, these methods would be inlinable.

Also useful would be methods to iterate over the one or 
zero bits in an integer or long, such as:
   int findIndexOfNextSetBit(int target, int pos);
   int findIndexOfNextUnsetBit(int target, int pos);
   int findIndexOfPreviousSetBit(int target, int pos);
   int findIndexOfPreviousUnsetBit(int target, int pos);
The "next" methods would search from position "pos" up to 
the end of the integer for a set bit, and would return the 
position of the bit thus found, or -1 if no match was 
found. The "prev" versions would do the same thing, but in 
the reverse direction.
Some compatibility with the names of the methods used in 
class BitSet would be nice.




Submitted On 01-MAR-2003
jonathanfinn
Here's a suggestion:
Many people using the >>/<</>>> operators will have been 
bitten by their unfortunate behaviour when the second 
operand falls outside the range 0-31 (for ints).

For instance:
1>>>0 is 1 (OK)
1>>>1 is 0 (OK)
1>>>2 is 0 (OK)
1>>>32 is 1 (bizarre! 0 is expected)
1>>>33 is 0 (OK)
1>>>-1 is 0 (bizarre! 2 is expected, since this is a left shift)
1>>>-32 is 1 (bizarre! 0 is expected)
1>>>-33 is 0 (OK)

Any shifting code in a loop is likely to hit one of these corner 
cases, which leads to very nasty and subtle bugs. (Typical 
loops are almost as likely to attempt shifting by -1 as by 32, 
so it can't be objected that negative shifts are meaningless 
or unimportant.)

Worse, it is *not easy* to fix the problem by writing your 
own method to get the expected results. All 3 shift operators 
are affected, for both int and long operands.

I suggest adding static methods shiftRight() and 
signedShiftRight() to both Integer and Long which 
give 'correct' results. There's no particular need for shiftLeft() 
methods since shiftRight() would do negative shifts correctly. 
Here's some sample code which I think works - it needed a 
lot of testing!

/* Returns the value of i shifted right by 'distance' bits.
This gives better results than >>> when distance falls 
outside the range 0 to 31.
Negative values of distance produce a left shift.
All bits 'shifted in' are zero, which means that for all values 
of distance >= 32 or <= -32 this returns 0.
*/
	public static int shiftRight(int i, int distance) {
		if (distance >= 0) {
			return (distance < 32) ? 
(i>>>distance) : 0;
		} else {
			return (distance > -32) ? (i<<-
distance) : 0;
		}
	}

/* Returns the value of i shifted right arithmetically 
by 'distance' bits. This means that bit 31 is always returned 
unchanged, and only bits 0-30 shift.
This gives better results than >> when distance falls outside 
the range 0 to 31.
Negative values of distance produce a left shift.
When shifting right, all bits 'shifted in' are the same as bit 
31; when shifting left, all bits 'shifted in' are zero.
*/
	public static int signedShiftRight(int i, int distance) 
{
		if (distance >= 0) {
			return (distance < 32) ? 
(i>>distance) : (i>>31);
		} else {
			final int signBit = i & 
0x80000000;
			return (distance > -32) ? (signBit 
| ((i<<-distance) &~ 0x80000000)) : signBit;
		}
	}



Submitted On 01-MAR-2003
jonathanfinn
testing


Submitted On 01-MAR-2003
jonathanfinn
Please could any new roll methods be defined to give correct 
results for rotations outside the range 0-31 (for ints) or 0-63 
(for longs).

i.e. rotating an int right by 0,32,-32,64,-64,... should all give 
the same result.

Following the example of Java's shift operators you might 
think rotating by 32 or more doesn't count - but it does! 80)


Submitted On 28-MAR-2003
jonathanfinn
A little off-topic, but it's alway struck me as strange that 
there is no way of writing binary numbers in Java (or C++). 
This makes it awkward to represent sets of flags, which is 
still a common programming technique. I don't understand 
why there's support for octal instead, which in my experience 
is almost never used.

Can I suggest a minor language change (!) allowing for 
numbers to be written in any base using a simple syntax 
such as 2_10111. In practise this would mostly be used for 
binary, but also provides an improved notation for octal (e.g. 
8_773), and would be occasionally useful for other bases up 
to 36.


Submitted On 19-OCT-2004
pergh99
Followup to jonathanfinn:

Or, as binary is about the only one missing from the most commonly used systems of notation, one would think 0b00101001 would be a welcome notation.




PLEASE NOTE: JDK6 is formerly known as Project Mustang