
Signature
Michael Powe michael@trollope.org Naugatuck CT USA
"It stands to reason that self-righteous, inflexible, single-minded,
authoritarian true believers are politically organized. Open-minded,
flexible, complex, ambiguous, anti-authoritarian people would just as
soon be left to mind their own f.cking business." - R.U. Sirius
A while ago I created a Base64 encoder/decoder, which required the use
of bit shifting.
However I had trouble with the shift operators.
So instead I created methods to unsign a byte and the shift the bits
left or right.
public int unsign(int b) {
if (b < 0) {
return b - Byte.MIN_VALUE*2;
} else {
return b;
}
}//This method is designed to unsign byte values.
public int shiftRight(int b, int n) {
return (int) (b / Math.pow(2, n));
}
public int shiftLeft(int b, int n) throws IOException {
return (int) (b * Math.pow(2, n));
}
//I think I had trouble because there is no unsigned left shift
operator (<<<) similar to >>>.
0x80000000 = 10000000000000000000000000000000 in binary.
That means that as bitmask >>>= 1 goes there is one less zero in the
binary number.
Thus number & bitmask will, assuming number equals 10010 in binary and
bitmask equals 10000 in binary, give this result
/* ~ is approximately*/
//giving out put
of
i ~= 0; number & bitmask = 10000 //bitmask = 10000 1
i ~= 1; number & bitmask = 0 //bitmask = 1000 0
i ~= 2; number & bitmask = 0 //bitmask = 100 0
i ~= 3; number & bitmask = 10 //bitmask = 10 1
i ~= 4; number & bitmask = 0 //bitmask = 1 0
Simple "bitwise and" logic (& operator).
//Quite frankly
numBits += startBit;
for(int i=startBit; i < numBits; ++i)
//is overly complicated; it is much easier to read as
for (int i = 0; i < numBits; ++i)
//numBits += startBit; has no real usage.
0x80000000 is essentially 10000000000000000000000000000000 in binary.
and if you notice 10000000000000000000000000000000 is 32 characters
long, this to me would indicate that 0x80000000 is the maximum value of
an int value, since int's are 32 bits.
//note that (int) 0xFFFFFFFF = -1; due to int's being signed values;
//(int) 0x80000001 = Integer.MIN_VALUE;
//(int) 0x80000000 = Integer.MAX_VALUE;
Because of that, this method can only work on int values.
So in order to change
public void printBits(int number, int startBit, int numBits)
//into
public void printBits(long number, int startBit, int numBits)
all you need to do is change 0x80000000 to 0x8000000000000000L
//note the L at the end is used to prevent a compiler error.
and of course all you have to do then is change
int bitmask;
into
long bitmask;
As for
"In the examples of usage, startBit always == 24 and numBits == 8.
This, of course, makes 32 bits. But, why start at 24? "
That depends entirely on the example usage.
On a side note; Since numBits = 8 that would actually print out 8
characters (bits) to the console. However it is true that since
"number" is an int in
//public void printBits(int number...) {...}
that number is 32 bits.
"What if I wanted to display the bits in a long or a double?"
Well I showed you how to do a long, but I don't know off the top of my
head how to do a double. Hopefully it is basically the same as
changing int to a long by using a different starting bitmask.
"Thanks for the help. I know this is probably knowledge I never will
use, but I just would like to grasp how this stuff works. "
Not if you ever have to work with encoding Base64! (see top of post)
//Hope that helps.
Remi Arntzen - 12 Jun 2005 03:16 GMT
OPPPS!
0x7FFFFFFF is Integer.MAX_VALUE
and 0x80000000 is simply used to get the int value with only the
highest order bit set.
and 0x80000000 is Integer.MIN_VALUE
//only off by one :-)
every thing else should be the same
/* **CORRECTED COPY***/
A while ago I created a Base64 encoder/decoder, which required the use
of bit shifting.
However I had trouble with the shift operators.
So instead I created methods to unsign a byte and the shift the bits
left or right.
public int unsign(int b) {
if (b < 0) {
return b - Byte.MIN_VALUE*2;
} else {
return b;
}
}//This method is designed to unsign byte values.
public int shiftRight(int b, int n) {
return (int) (b / Math.pow(2, n));
}
public int shiftLeft(int b, int n) throws IOException {
return (int) (b * Math.pow(2, n));
}
//I think I had trouble because there is no unsigned left shift
operator (<<<) similar to >>>.
0x80000000 = 10000000000000000000000000000000 in binary.
That means that as bitmask >>>= 1 goes there is one less zero in the
binary number. 0x80000000 is used simply to get the int value with
only its highest order bit set.
//note that (int) 0xFFFFFFFF = -1; due to int's being signed values;
//(int) 0x7FFFFFFF = Integer.MAX_VALUE;
//(int) 0x80000000 = Integer.MIN_VALUE;
Thus (number & bitmask) will, assuming number equals 10010 in binary
and
bitmask equals 10000 in binary, give this result
/* ~ is approximately*/
//giving out put of
i ~= 0; number & bitmask = 10000 //bitmask = 10000 1
i ~= 1; number & bitmask = 0 //bitmask = 1000 0
i ~= 2; number & bitmask = 0 //bitmask = 100 0
i ~= 3; number & bitmask = 10 //bitmask = 10 1
i ~= 4; number & bitmask = 0 //bitmask = 1 0
Simple "bitwise and" logic (& operator).
//Quite frankly
numBits += startBit;
for(int i=startBit; i < numBits; ++i)
//is overly complicated, and is much easier to read as
for (int i = 0; i < numBits; ++i)
//numBits += startBit; has no real usage.
Because of the bitmask, this method can only work on int values.
So in order to change
public void printBits(int number, int startBit, int numBits)
//into
public void printBits(long number, int startBit, int numBits)
all you need to do is change 0x80000000 to 0x8000000000000000L
//note the L at the end is used to prevent a compiler error.
and of course all you have to do then is change
int bitmask;
into
long bitmask;
As for
"
In the examples of usage, startBit always == 24 and numBits == 8.
This, of course, makes 32 bits. But, why start at 24
? "
That depends entirely on the example usage.
On a side note; Since numBits = 8 that would actually print out 8
characters (bits) to the console. However it is true that since
"number" is an int in
//public void printBits(int number...) {...}
that number is 32 bits.
"
What if I wanted to display the bits in a long or a double
?"
Well I showed you how to do a long, but I don't know off the top of my
head how to do a double. Hopefully it is basically the same as
changing int to a long by using a different starting bitmask.
//Hope that helps.
/* **CORRECTED COPY***/
Michael Powe - 12 Jun 2005 22:40 GMT
>>>>> "ninja" == ninja java <Remi.Arntzen@gmail.com> writes:
ninja> A while ago I created a Base64 encoder/decoder, which
ninja> required the use of bit shifting. However I had trouble
ninja> with the shift operators. So instead I created methods to
ninja> unsign a byte and the shift the bits left or right.
[ ... ]
Your explanations really help. Thank you. I'm working on it now. I
really appreciate your taking the time to explain this.
mp

Signature
Michael Powe michael@trollope.org Naugatuck CT USA
"In every country and in every age, the priest has been hostile to
liberty. He is always in alliance with the despot, abetting his
abuses in return for protection to his own." -- Thomas Jefferson to
Horatio G. Spafford, 1814. ME 14:119