|
Comments
|
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
|