Manipulating hexadecimal values in java - java

I'm tying to make a Linear Congruential random number generator, and I want to select, say the first 16 bits of a 64-bit length hexadecimal value. How Can I do this in java? I've already created a (very) basic generated number based on the time of day.
My formula:
seed = 0x5D588B656C078965L * cal.get(Calendar.HOUR_OF_DAY) + 0x0000000000269EC3;
I just want to select the first 16 bits of this, I tried to think of how I would do this with an integer but the I don't think i can apply the same concepts here. Thanks!

If you want a long that has the first 16 bits and zeroes in the other positions, you can either use a bit mask or shifting.
Assuming by "first 16 bits" you mean the highest-order bits, then the mask looks like this:
long mask = 0xffff000000000000;
so that a '1' is in each bit position you want to retain, and a 0 elsewhere. Then do a logical 'and' of this with your original integer:
long result = seed & mask;
The other way is to shift your original to the right 48 bits, then left again 48 bits.

Bit shift:
long value = seed >>> 48;
or you can save it in an int:
int value = (int)(seed >> 48);
Usually, you would use the last bits of the seed to produce the random number, which makes for a one-way mod operation (ie "more random"), so:
seed & 0xFFFF

Related

Assign negative int to long in java

I've 2 integer values stored in a bytebuffer, in little-endian format. These integers are actually the 32-bit pieces of a long. I've to store them as a class' member variables, loBits and hiBits.
This is what I did:
long loBits = buffer.getInt(offset);
long hiBits = buffer.getInt(offset + Integer.BYTES);
I want to know why directly assigning signed int to long is wrong. I kind of know what's going on, but would really appreciate an explanation.
The int I read from the buffer is signed (because Java). If it is negative then directly assigning it to a long value (or casting it like (long)) would change all the higher order bits in the long to the signed bit value.
For e.g. Hex representation of an int, -1684168480 is 9b9da0e0. If I assign this int to a long, all higher order 32 bits would become F.
int negativeIntValue = -1684168480;
long val1 = negativeIntValue;
long val2 = (long) negativeIntValue;
Hex representation of:
negativeIntValue is 0x9b9da0e0
val1 is 0xffffffff9b9da0e0
val2 is 0xffffffff9b9da0e0
However, if I mask the negativeIntValue with 0x00000000FFFFFFFFL, I get a long which has the same hex representation as negativeIntValue and a positive long value of 2610798816.
So my questions are:
Is my understanding correct?
Why does this happen?
Yes, your understanding is correct (at least if I understood your understanding correctly).
The reason this happens is because (most) computers use 2's complement to store signed values. So when assigning a smaller datatype to a larger one, the value is sign extended meaning that the excess part of the datatype is filled with 0 or 1 bits depending on whether the original value was positive or negative.
Also related is the difference between >> and >>> operators in Java. The first one performs sign extending (keeping negative values negative) the second one does not (shifting a negative value makes it positive).
The reason for this is that negative values are stored as two's complement.
Why do we use two's complement?
In a fixed width numbering system what happens, if you substract 1 from 0?
0000b - 0001b -> 1111b
and what is the next lesser number to 0? It is -1.
Therfore we thread a binary number with all bits set (for a signed datatype) as -1
The big advantage is that the CPU does not need to do any special operation when changing from positive to negative numbers. It handles 5 - 3 the same as 3 - 5

Set particular Bit in Java long value

I have one long value and Set Particular bit by converting hexadecimal value.
long l = 4;
long output; //output is 84 if i want set 7th bit (1000 0100)
same way is long is 7 then output is 87 so how to set particular bit inside long value.
Requirement:
I have to send one byte to server by proper formatting.
Client gives following thing.
1. Whether 7th bit set or not set.
2. One integer value (like 4,5,6,7 etc.)
Now I have generate string or decimal (2H) that format as client parameter.
You need to do a bitwise or with the value of the bit.
The value of the bit you can find by shifting 1L the correct number of bits to the left. (Don't forget the L, without that you're shifting the int 1.)
Bitwise or can be done with the | operator in Java.
So the code becomes:
long output = l | (1L << 7);

What is the purpose of the unsigned right shift operator ">>>" in Java?

I understand what the unsigned right shift operator ">>>" in Java does, but why do we need it, and why do we not need a corresponding unsigned left shift operator?
The >>> operator lets you treat int and long as 32- and 64-bit unsigned integral types, which are missing from the Java language.
This is useful when you shift something that does not represent a numeric value. For example, you could represent a black and white bit map image using 32-bit ints, where each int encodes 32 pixels on the screen. If you need to scroll the image to the right, you would prefer the bits on the left of an int to become zeros, so that you could easily put the bits from the adjacent ints:
int shiftBy = 3;
int[] imageRow = ...
int shiftCarry = 0;
// The last shiftBy bits are set to 1, the remaining ones are zero
int mask = (1 << shiftBy)-1;
for (int i = 0 ; i != imageRow.length ; i++) {
// Cut out the shiftBits bits on the right
int nextCarry = imageRow & mask;
// Do the shift, and move in the carry into the freed upper bits
imageRow[i] = (imageRow[i] >>> shiftBy) | (carry << (32-shiftBy));
// Prepare the carry for the next iteration of the loop
carry = nextCarry;
}
The code above does not pay attention to the content of the upper three bits, because >>> operator makes them
There is no corresponding << operator because left-shift operations on signed and unsigned data types are identical.
>>> is also the safe and efficient way of finding the rounded mean of two (large) integers:
int mid = (low + high) >>> 1;
If integers high and low are close to the the largest machine integer, the above will be correct but
int mid = (low + high) / 2;
can get a wrong result because of overflow.
Here's an example use, fixing a bug in a naive binary search.
Basically this has to do with sign (numberic shifts) or unsigned shifts (normally pixel related stuff).
Since the left shift, doesn't deal with the sign bit anyhow, it's the same thing (<<< and <<)...
Either way I have yet to meet anyone that needed to use the >>>, but I'm sure they are out there doing amazing things.
As you have just seen, the >> operator automatically fills the
high-order bit with its previous contents each time a shift occurs.
This preserves the sign of the value. However, sometimes this is
undesirable. For example, if you are shifting something that does not
represent a numeric value, you may not want sign extension to take
place. This situation is common when you are working with pixel-based
values and graphics. In these cases you will generally want to shift a
zero into the high-order bit no matter what its initial value was.
This is known as an unsigned shift. To accomplish this, you will use
java’s unsigned, shift-right operator,>>>, which always shifts zeros
into the high-order bit.
Further reading:
http://henkelmann.eu/2011/02/01/java_the_unsigned_right_shift_operator
http://www.java-samples.com/showtutorial.php?tutorialid=60
The signed right-shift operator is useful if one has an int that represents a number and one wishes to divide it by a power of two, rounding toward negative infinity. This can be nice when doing things like scaling coordinates for display; not only is it faster than division, but coordinates which differ by the scale factor before scaling will differ by one pixel afterward. If instead of using shifting one uses division, that won't work. When scaling by a factor of two, for example, -1 and +1 differ by two, and should thus differ by one afterward, but -1/2=0 and 1/2=0. If instead one uses signed right-shift, things work out nicely: -1>>1=-1 and 1>>1=0, properly yielding values one pixel apart.
The unsigned operator is useful either in cases where either the input is expected to have exactly one bit set and one will want the result to do so as well, or in cases where one will be using a loop to output all the bits in a word and wants it to terminate cleanly. For example:
void processBitsLsbFirst(int n, BitProcessor whatever)
{
while(n != 0)
{
whatever.processBit(n & 1);
n >>>= 1;
}
}
If the code were to use a signed right-shift operation and were passed a negative value, it would output 1's indefinitely. With the unsigned-right-shift operator, however, the most significant bit ends up being interpreted just like any other.
The unsigned right-shift operator may also be useful when a computation would, arithmetically, yield a positive number between 0 and 4,294,967,295 and one wishes to divide that number by a power of two. For example, when computing the sum of two int values which are known to be positive, one may use (n1+n2)>>>1 without having to promote the operands to long. Also, if one wishes to divide a positive int value by something like pi without using floating-point math, one may compute ((value*5468522205L) >>> 34) [(1L<<34)/pi is 5468522204.61, which rounded up yields 5468522205]. For dividends over 1686629712, the computation of value*5468522205L would yield a "negative" value, but since the arithmetically-correct value is known to be positive, using the unsigned right-shift would allow the correct positive number to be used.
A normal right shift >> of a negative number will keep it negative. I.e. the sign bit will be retained.
An unsigned right shift >>> will shift the sign bit too, replacing it with a zero bit.
There is no need to have the equivalent left shift because there is only one sign bit and it is the leftmost bit so it only interferes when shifting right.
Essentially, the difference is that one preserves the sign bit, the other shifts in zeros to replace the sign bit.
For positive numbers they act identically.
For an example of using both >> and >>> see BigInteger shiftRight.
In the Java domain most typical applications the way to avoid overflows is to use casting or Big Integer, such as int to long in the previous examples.
int hiint = 2147483647;
System.out.println("mean hiint+hiint/2 = " + ( (((long)hiint+(long)hiint)))/2);
System.out.println("mean hiint*2/2 = " + ( (((long)hiint*(long)2)))/2);
BigInteger bhiint = BigInteger.valueOf(2147483647);
System.out.println("mean bhiint+bhiint/2 = " + (bhiint.add(bhiint).divide(BigInteger.valueOf(2))));

Java - derby - unsigned int

I would like that one of my columns in a specific table would not get negative numbers.
Is there a way to declare an unsigned int in derby DB ?
Q: Is there a way to declare a column "unsigned int" in a Derby DB table?
A: I believe answer is "No":
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
... HOWEVER ...
You should easily be able to "CAST" the stored value in any query:
The answer is no. Java (unfortunately) has no support for unsigned arithmetics.
But you can still use Java's int and make your own methods to do unsigned arithmetic, like this. Even better is to create an UnsignedInteger class and let it handle all that arithmetic.
I don't know if it's worth it though. You can just use long as jtahlborn suggests.
Java does NOT support the type unsigned int, as opposed to C or C++.
On the other hand, there is a simple way to circumvent this limitation by using:
An intermediate long variable/literal
A cast to (int)
First, let us note that both signed and unsigned int have the same number of bits; they are both 32 bits in size.
The main difference is, that for signed integers the MSB (Most Significant Bit) or bit 0 is used to indicate that the actual integer is negative or positive.
If this bit is set to 1 the integer is negative, if it is set to 0, the integer is negative. So, you will end up with 31 bits for the value of the integer, and 1 bit for the sign.
For unsigned integers, all the 32 bits are used to represent the value of the integer. You can now have larger numbers.
The signed integers range from -2^31 to (2^31 - 1)
The unsigned integers range from 0 to (2^32 - 1)
To show the size limitation issue, try to compile the following snippet:
public static void main (String[] args){
int i = 2_147_483_648;//This line will generate a compiler error
}
}
The compiler will complain saying integer number too large.
Let us see how we can circumvent this and still store this number in a Java integer, and retrieve it back.
The idea behind the proposed solution stems from the fact that a series of bits is interpreted to mean something. It could be a representation of an image, a Java object, a C struct, a character, etc.
You "interpret" the series of bits based on what you "expect" that series of bits to represent. If you are expecting a character, you might be looking to match the series against an ASCII table. If you are expecting an image, you might be looking to decode a JPEG.
Now, and coming back to integers, if you are looking for signed integers you will interpret the MSB as the sign bit. If you are looking for unsigned integers you will interpret the MSB as part of the value.
To give an example, let us assume that you have the following series of 32 bits:
in hex 0x8000_0000 or in binary 0b1000_0000_0000_0000_0000_0000_0000_0000
The MSB is set to 1 all other bits are 0.
If you are looking for/expecting a signed integer these 32 bits would be interpreted as the representation of the negative decimal number -2_147_483_648
If you are looking for/expecting an unsigned integer these same 32 bits would be interpreted as the representation of the positive decimal number 2_147_483_648
Hence, the solution would be to store the values in a signed 32-bit integer and interpret them as an unsigned 32-bit integer.
Here is how we will modify the previous snippet and save 2_147_483_648 into an integer value and be able to print it correctly.
To do so, we will:
First, use a long intermediate datatype/value
Then cast that value to int to save it
Finally, mask/ignore & the extra bits and display it
public static void main (String[] args){
//1. cast a 64-bit long value that fits into a 32-bit int
int i = (int)2_147_483_648L;
//2. Mask the extra long bits
System.out.println(i & 0x0000_0000_FFFF_FFFFL);
}
}
The long variable can hold 64 bits, and its MSB, or sign bit, is not affected by its first 32 bits. You will notice a bitwise operation happening here:
i & 0x0000_0000_FFFF_FFFFL
This is telling the compiler to ignore, or mask, all the bits that are beyond the first 32 bits we are interested in. Our integer is 32-bit.
If you want to do some arithmetic operation on the int value before saving it, you could resort again to a long intermediate variable.
Here is how, and this will be the proposed solution:
public static void main (String[] args){
int i = (int)2_147_483_648L;
int j = 1_000_000;
long tempL = i + j;//Use a temp long to perform the operations
i = (int)tempL; //We save back into i and store in a DB for example
//Now we use the saved value to display it, for example
System.out.println(i & 0x0000_0000_FFFF_FFFFL);
}
}
Good luck and hope the above helps!

Declaring masks for bitwise operations

I'm new to low level operations like this, I'm hoping someone can point out the obvious mistake I must be making here.
//Input value - 00111100
//I want to get the value of the bits at indexes 1-3 i.e 0111.
byte mask = (byte)0x00001111; // This gives 17 not the 15 I'd expect
byte shifted = (byte)(headerByte >> 3);
//shifted is 7 as expected
byte frameSizeValue = (byte)(shifted & mask); //Gives 1 not 7
It looks like the problem lies with the way the mask is defined, but I can't see how to fix it.
First of all 0x00001111 is in hex, which is a larger number than 255 - 16^3 + 16^2 + 16 + 1 = 4369 and byte overflows. Look here how to represent binary numbers or just use shifted & 15.
Your mask needs to be binary 00001111, which is equal to hex 0x0F.
byte mask = (byte)0x0F;
With java 7 you can create binary literals
byte binaryLit = (byte)0b00001111;
0xsomenumbers is a hex literal, and pre java7 there is no support for binaries.
You say you want to mask the first three bits but as Petar says, 0x001111 are not bits. If you want to mask the three bits you need to mask with 7

Categories