best way to reverse bytes in an int in java - java

What's the best way to reverse the order of the 4 bytes in an int in java??

You can use Integer.reverseBytes:
int numBytesReversed = Integer.reverseBytes(num);
There's also Integer.reverse that reverses every bit of an int
int numBitsReversed = Integer.reverse(num);
java.lang.Integer API links
public static int reverseBytes(int i)
Returns the value obtained by reversing the order of the bytes in the two's complement representation of the specified int value.
public static int reverse(int i)
Returns the value obtained by reversing the order of the bits in the two's complement binary representation of the specified int value.
Solution for other primitive types
There are also some Long, Character, and Short version of the above methods, but some are notably missing, e.g. Byte.reverse. You can still do things like these:
byte bitsRev = (byte) (Integer.reverse(aByte) >>> (Integer.SIZE - Byte.SIZE));
The above reverses the bits of byte aByte by promoting it to an int and reversing that, and then shifting to the right by the appropriate distance, and finally casting it back to byte.
If you want to manipulate the bits of a float or a double, there are Float.floatToIntBits and Double.doubleToLongBits that you can use.
See also
Wikipedia/Bitwise operation
Bit twiddling hacks

I agree that polygenelubricants's answer is the best one. But just before I hit that, I had the following:
int reverse(int a){
int r = 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
return r;
}
shifting the input right, the output left by 8 bits each time and OR'ing the least significant byte to the result.

Related

Work a Bitwise operation backwards

I need to know how to do this backwards so that it will work for all of the options. If I start with shift i can get radix so How would i get shift from starting with radix.
int shift = 4; //3 will give octal base 4 will give Hex base 1 will give binary base
int radix = 1 << shift; // this comes out as 16
So Like i said above how would i get this to go the otherway
int radix = 16;
int shift =(some operation);
Also to make this work for if radix is 8, 2 or 16
There's lots of useful methods in the Integer class. Try
int shift = Integer.numberOfTrailingZeros(radix).
Try with this method,
public static int radixToShift(int radix){
int shift = 0;
for(int i=0;radix >> i >1;i++){
shift++;
}
return shift;
}
Code
int shift = 4;
int radix = 1 << shift;
System.out.println("Radix :: "+radix);
System.out.println("Shift :: "+radixToShift(radix));
Output
Radix :: 16
Shift :: 4

Bit shift of signed byte strange behaviour

I have written a function to print the bit out in a byte. This happens by setting the most significant bit to 1 comparing it to the inputbyte and if it is also 1 printing "1" else "0". The comparison byte is then shifted right.
How do I achieve starting with 10000000 and shifting to 01000000 then 00100000...
I believe my problem is caused by promotion to int then recasting but I don't see the solution.
package errorreporting;
public class ErrorReporting {
ErrorReporting() {
}
public static void main(String[] args) {
ErrorReporting myError = new ErrorReporting();
byte myByte = 16;
myError.printByteArray(myByte);
}
public void printByteArray(byte inputByte) {
// print out 1 or 0
byte comparison = -128;
for (int x = 0; x < 8; x++) {
if ((inputByte & comparison) != 0) {
System.out.print("1");
} else {
System.out.print("0");
}
// System.out.print(" comparison : " + comparison);
comparison = (byte) (comparison >>> 1);
}
System.out.println(" : " + inputByte);
}
}
This post has some info : Java bitshift strangeness
I believe my problem is caused by promotion to int then recasting
Yes, it is a combination of some implicit and explicit casting and sign extension:
All arguments are first promoted to int before the shift operation takes place, see also https://stackoverflow.com/a/3948303/1611055
Due to 1., your unsigned shift operator >>> does not help - it correctly shifts a 0 into the leftmost position, but since the source argument -128 has been promoted to int before the shift is applied (resulting in 0xffffff80), you end up with 0x7fffffc0 after the first shift.
The simplest solution is to use an int for your mask:
int comparison = 0x80; // -128;
Theoretically, you could also still use a byte for the mask, but then you need to explicitly convert it to an int while discarding the sign bit at the same time, before applying the shift operator, like this:
byte comparison = -128;
...
comparison = (byte)( (((int) comparison) & 0xff) >>> 1);
((int) comparison) & 0xff) assumes that the byte should really be "unsigned" and converts it to the corresponding "unsigned" int value. Then, you can apply the shift operator (>> or >>> does not matter, since we have a positive int value in any case) and cast it back to a byte.

Java results differ for (int)Math.pow(2,x) and 1<<x

Why do the following two operations yield different results in Java for x = 31 or 32 but the same results for x=3?
int x=3;
int b = (int) Math.pow(2,x);
int c = 1<<x;
Results:
x=32: b=2147483647; c=1;
x=31: b=2147483647; c=-2147483648;
x=3: b=8 ; c=8
There are multiple issues at play:
An int can only store values between -2147483648 and 2147483647.
1 << x only uses the lowest five bits of x. Thus, 1 << 32 is by definition the same as 1 << 0.
Shift operations are performed on the two's-complement integer representation of the value of the left operand; this explains why 1 << 31 is negative.
Math.pow(2, 32) returns a double.
(int)(d), where d is a double greater than 2147483647 returns 2147483647 ("the largest representable value of type int").
What this interview question does is show that (int)Math.pow(2, x) and 1 << x are not equivalent for values of x outside the 0...30 range.
P.S. It is perhaps interesting to note that using long in place of int (and 1L in place of 1) would give yet another set of results different from the other two. This holds even if the final results are converted to int.
According to the documentation Math.pow will promote both of its arguments to double and return double. Obviously when the returned result is double and you cast it to int you'll get only the highest 32 bits and the rest will be truncated - hence you always get the (int) Math.pow(2,x); value. When you do bitshift you always work with ints and hence an overflow occurs.
Consider the limits of the type int. How large a number can it hold?
Here's a micro-benchmark for the case of a long. On my laptop (2.8GHz), using shift instead of Math.pow is over 7x faster.
int limit = 50_000_000;
#Test
public void testPower() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = (long)Math.pow(2,p);
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 3.758 s
}
#Test
public void testShift() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = 1L << p;
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 0.523 s
}
int is 32 bits in size and since it is signed (by default), the first bit is used for the sign. When you shift left 31 bits, you get the Two's Compliment, which is -(2^32). When you shift left 32 bits, it just loops all the way back around to 1. If you were to do this shifting with longs instead of ints, you would get the answers you expect (that is until you shift 63+ bits).

represent an integer using binary in java language

Here is the problem:
You're given 2 32-bit numbers, N & M, and two bit positions, i & j. write a method to set all bits between i and j in N equal to M (e.g. M becomes a substring of N at locating at i
and starting at j)
For example:
input:
int N = 10000000000, M = 10101, i = 2, j = 6;
output:
int N = 10001010100
My solution:
step 1: compose one mask to clear sets from i to j in N
mask= ( ( ( ((1<<(31-j))-1) << (j-i+1) ) + 1 ) << i ) - 1
for the example, we have
mask= 11...10000011
step 2:
(N & mask) | (M<<i)
Question:
what is the convenient data type to implement the algorithm? for example
we have int n = 0x100000 in C, so that we can apply bitwise operators on n.
in Java, we have BitSet class, it has clear, set method, but doesnt support
left/right shift operator; if we use int, it supports left/right shift, but
doesnt have binary representation (I am not talking about binary string representation)
what is the best way to implement this?
Code in java (after reading all comments):
int x = Integer.parseInt("10000000000",2);
int x = Integer.parseInt("10101",2);
int i = 2, j = 6;
public static int F(int x, int y, int i, int j){
int mask = (-1<<(j+1)) | (-1>>>(32-i));
return (mask & x ) | (y<<i);
}
the bit-wise operators |, &, ^ and ~ and the hex literal (0x1010) are all available in java
32 bit numbers are ints if that constraint remains int will be a valid data type
btw
mask = (-1<<j)|(-1>>>(32-i));
is a slightly clearer construction of the mask
Java's int has all the operations you need. I did not totally understand your question (too tired now), so I'll not give you a complete answer, just some hints. (I'll revise it later, if needed.)
Here are j ones in a row: (1 << j)-1.
Here are j ones in a row, followed by i zeros: ((1 << j) - 1) << i.
Here is a bitmask which masks out j positions in the middle of x: x & ~(((1 << j) - 1) << i).
Try these with Integer.toBinaryString() to see the results. (They might also give strange results for negative or too big values.)
I think you're misunderstanding how Java works. All values are represented as 'a series of bits' under the hood, ints and longs are included in that.
Based on your question, a rough solution is:
public static int applyBits(int N, int M, int i, int j) {
M = M << i; // Will truncate left-most bits if too big
// Assuming j > i
for(int loopVar = i; loopVar < j; loopVar++) {
int bitToApply = 1 << loopVar;
// Set the bit in N to 0
N = N & ~bitToApply;
// Apply the bit if M has it set.
N = (M & bitToApply) | N;
}
return N;
}
My assumptions are:
i is the right-most (least-significant) bit that is being set in N.
M's right-most bit maps to N's ith bit from the right.
That premature optimization is the root of all evil - this is O(j-i). If you used a complicated mask like you did in the question you can do it in O(1), but it won't be as readable, and readable code is 97% of the time more important than efficient code.

Port of Random generator from C to Java?

George Marsaglia has written an excellent random number generator that is extremely fast, simple, and has a much higher period than the Mersenne Twister. Here is the code with a description:
good C random number generator
I wanted to port the CMWC4096 code to Java, but it uses several unsigned datatypes so I am not sure how to do this properly. Here is the full C code:
/* choose random initial c<809430660 and */
/* 4096 random 32-bit integers for Q[] */
static unsigned long Q[4096],c=362436;
unsigned long CMWC4096(void) {
unsigned long long t, a=18782LL;
static unsigned long i=4095;
unsigned long x,r=0xfffffffe;
i = (i+1) & 4095;
t = a*Q[i] + c;
c = (t>>32);
x = t + c;
if (x < c) {
x++;
c++;
}
return (Q[i] = r - x);
}
Can anyone port this to Java? How does this work when you only have signed numbers available?
EDIT: Thanks everybody for the quick answers! For the first 100 million numbers this java code seems to produce the same result as the C code. It is 3 times faster than Java's java.util.Random.
public class ComplimentaryMultiplyWithCarryRandom {
/**
* Choose 4096 random 32-bit integers
*/
private long[] Q;
/**
* choose random initial c<809430660
*/
private long c = 362436;
private int i;
public ComplimentaryMultiplyWithCarryRandom() {
Random r = new Random(1);
Q = new long[4096];
// TODO initialize with real random 32bit values
for (int i = 0; i < 4096; ++i) {
long v = r.nextInt();
v -= Integer.MIN_VALUE;
Q[i] = v;
}
i = 4095;
}
int next() {
i = (i + 1) & 4095;
long t = 18782 * Q[i] + c;
c = t >>> 32;
long x = (t + c) & 0xffffffffL;
if (x < c) {
++x;
++c;
}
long v = 0xfffffffeL - x;
Q[i] = v;
return (int) v;
}
}
Most of the time there is no need to use larger numeric types for simulating unsigned types in Java.
For addition, subtraction, multiplication, shift left, the logical operations, equality
and casting to a smaller numeric type
it doesn't matter whether the operands are signed or unsigned,
the result will be the same regardless, viewed as a bit pattern.
For shifting to the right use >> for signed, >>> for unsigned.
For signed casting to a larger type just do it.
For unsigned casting from a smaller type to a long use & with a mask of type long for the smaller type.
E.g., short to long: s & 0xffffL.
For unsigned casting from a smaller type to an int use & with a mask of type int.
E.g., byte to int: b & 0xff.
Otherwise do like in the int case and apply a cast on top.
E.g., byte to short: (short) (b & 0xff).
For the comparison operators < etc. and division the easiest is to cast to a larger type and do the operation there.
But there also exist other options, e.g. do comparisons after adding an appropriate offset.
Can anyone port this to Java? How does
this work when you only have signed
numbers available?
No Stress! a=18782 so the largest t could ever be is not large enough to cause signed vs. unsigned problems. You would have to "upgrade" the result of using Q to a value equal to a 32-bit unsigned number before using it anywhere. e.g. if Q is an int (32-bit signed) then you'd have to do this before using it in the t=a*Q[i]+c statement, e.g.
t=a*(((long)Q[i])&0xffffffffL)+c
where this (((long)Q[i])&0xffffffffL) business promotes Q[i] to a 64-bit # and ensures its high 32 bits are 0's. (edit: NOTE: you need 0xffffffffL here. Java does the wrong thing if you use 0xffffffff, it seems like it "optimizes" itself to the wrong answer & you get a negative number if Q[i]'s high bit is 1.)
You should be able to verify this by running the algorithms in C++ and Java to compare the outputs.
edit: here's a shot at it. I tried running it in C++ and Java for N=100000; they both match. Apologies if I used bad Java idioms, I'm still fairly new to Java.
C++:
// marsaglia2003.cpp
#include <stdio.h>
#include <stdlib.h> // for atoi
class m2003
{
enum {c0=362436, sz=4096, mask=4095};
unsigned long Q[sz];
unsigned long c;
short i;
public:
m2003()
{
// a real program would seed this with a good random seed
// i'm just putting in something that makes the output interesting
for (int j = 0; j < sz; ++j)
Q[j] = j + (j << 16);
i = 4095;
c = c0;
}
unsigned long next()
{
unsigned long long t, a=18782LL;
unsigned long x;
unsigned long r=0xfffffffe;
i = (i+1)&mask;
t=a*Q[i]+c;
c=(unsigned long)(t>>32);
x=(unsigned long)t + c;
if (x<c)
{
x++;
c++;
}
return (Q[i]=r-x);
}
};
int main(int argc, char *argv[])
{
m2003 generator;
int n = 100;
if (argc > 1)
n = atoi(argv[1]);
for (int i = 0; i < n; ++i)
{
printf("%08x\n", generator.next());
}
return 0;
}
java: (slower than compiled C++ but it matches for N=100000)
// Marsaglia2003.java
import java.util.*;
class Marsaglia2003
{
final static private int sz=4096;
final static private int mask=4095;
final private int[] Q = new int[sz];
private int c=362436;
private int i=sz-1;
public Marsaglia2003()
{
// a real program would seed this with a good random seed
// i'm just putting in something that makes the output interesting
for (int j = 0; j < sz; ++j)
Q[j] = j + (j << 16);
}
public int next()
// note: returns a SIGNED 32-bit number.
// if you want to use as unsigned, cast to a (long),
// then AND it with 0xffffffffL
{
long t, a=18782;
int x;
int r=0xfffffffe;
i = (i+1)&mask;
long Qi = ((long)Q[i]) & 0xffffffffL; // treat as unsigned 32-bit
t=a*Qi+c;
c=(int)(t>>32);
// because "a" is relatively small this result is also small
x=((int)t) + c;
if (x<c && x>=0) // tweak to treat x as unsigned
{
x++;
c++;
}
return (Q[i]=r-x);
}
public static void main(String args[])
{
Marsaglia2003 m2003 = new Marsaglia2003();
int n = 100;
if (args.length > 0)
n = Integer.parseInt(args[0]);
for (int i = 0; i < n; ++i)
{
System.out.printf("%08x\n", m2003.next());
}
}
};
If you are implementing an RNG in Java, it is best to sub-class the java.util.Random class and over-ride the protected next(int) method (your RNG is then a drop-in replacement for java.util.Random). The next(int) method is concerned with randomly-generated bits, not what vales those bits might represent. The other (public) methods of java.util.Random use these bits to construct random values of different types.
To get around Java's lack of unsigned types you usually store numbers in a bigger variable type (so shorts get upgraded to ints, ints to long). Since you're using long variables here, you're going to have to step up to BigInteger, which will probably wreck any speed gains that you're getting out of the algorithm.
You can use signed numbers provided the values don't overflow...for example long in java is a 64 bit signed integer. However the intent in this algorithm seems to be to use a 64 bit unsigned value, and if so I think you would be out of luck with the basic types.
You could use the multiprecision integers provided in the java class libraries (BigInteger). Or you could implement your own 64 bit unsigned type as an Object containing two java longs to represent the least significant and most significant words (but you'd have to implement the basic arithmetic operations yourself in the class).
Note: In your C code, I inferred that long is 32 bits wide, and long long is 64 bits wide.
Here is my way of porting that code to Java with the minimum number of changes:
/* choose random initial 0<=c<809430660 and */
/* 4096 random 32-bit integers for Q[] */
int[] Q = new int[4096];
int c = 362436;
int i = 4095;
int CMWC4096() {
long a = 18782;
int r = 0xfffffffe;
i = (i + 1) & 4095;
long t = a * Q[i] + c;
c = (int)(t >>> 32);
int x = (int)(t + c);
if (0 <= x && x < c) {
x++;
c++;
}
return (Q[i] = r - x);
}

Categories