Set particular Bit in Java long value - java

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);

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

Manipulating hexadecimal values in 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

Long.parseLong throws NumberFormatException for valid hex string [duplicate]

We have a J2ME application that needs to read hex numbers. The application is already too big for some phones so We try not to include any other codec or write our own function to do this.
All the numbers are 64-bit signed integers in hex, when we use Long.ParseLong(hex, 16), it handles positive numbers correctly but it throws exception on negative numbers,
long l = Long.parseLong("FFFFFFFFFFFFFFFF", 16);
How can we get -1 from that hex string using classes provided in Java itself?
Some people may suggest we should write our hex as -1 as Java expected. Sorry, the format is fixed by the protocol and we can't change it.
Your problem is that parseLong() does not handle two's complement - it expects the sign to be present in the form of a '-'.
If you're developing for the CDC profile, you can simple use
long l = new BigInteger("FFFFFFFFFFFFFFFF", 16).longValue()
But the CLDC profile doesn't have that class. There, the easiest way to do what you need is probably to split up the long, parse it in two halves and recombine them. This works:
long msb = Long.parseLong("FFFFFFFF", 16);
long lsb = Long.parseLong("FFFFFFFF", 16);
long result = msb<<32 | lsb;
UPDATE
As of Java 8, you can use parseUnsignedLong():
long l = Long.parseUnsignedLong("FFFFFFFFFFFFFFFF", 16);
Parse it in chunks.
long l = (Long.parseLong("FFFFFFFFF",16)<<32) | Long.parseLong("FFFFFFFF",16);
Worse case scenario, you could check to see if the string is 16 characters that begins with an 8-F, and if so, change that to the equivalent character w/o the most significant bit set (i.e. subtract 8 from that digit), parse the result, and add the parsed value to the lower bound of a signed long? (Essentially just doing the 2's complement yourself.)

Bitwise negation gives unexpected result

I am trying to write a bitwise calculator in java, something that you could input an expression such as ~101 and it would give back 10 however when i run this code
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
Integer a = Integer.valueOf("101", 2);
System.out.println(Integer.toString(~a,2));
}
}
it outputs -110 why?
You are assuming that 101 is three bits long. Java doesn't support variable length bit operations, it operates on a whole int of bits, so ~ will be the not of a 32 bit long "101".
--- Edited after being asked "How can I fix this?" ---
That's a really good question, but the answer is a mix of "you can't" and "you can achieve the same thing by different means".
You can't fix the ~ operator, as it does what it does. It would sort of be like asking to fix + to only add the 1's place. Just not going to happen.
You can achieve the desired operation, but you need a bit more "stuff" to get it going. First you must have something (another int) that specifies the bits of interest. This is typically called a bit mask.
int mask = 0x00000007; // just the last 3 bits.
int masked_inverse = (~value) & mask;
Note that what we did was really invert 32 bits, then zeroed out 29 of those bits; because, they were set to zero in the mask, which means "we don't care about them". This can also be imagined as leveraging the & operator such that we say "if set and we care about it, set it".
Now you will still have 32 bits, but only the lower 3 will be inverted. If you want a 3 bit data structure, then that's a different story. Java (and most languages) just don't support such things directly. So, you might be tempted to add another type to Java to support that. Java adds types via a class mechanism, but the built-in types are not changeable. This means you could write a class to represent a 3 bit data structure, but it will have to handle ints internally as 32 bit fields.
Fortunately for you, someone has already done this. It is part of the standard Java library, and is called a BitSet.
BitSet threeBits = new BitSet(3);
threeBits.set(2); // set bit index 2
threeBits.set(0); // set bit index 0
threeBits.flip(0,3);
However, such bit manipulations have a different feel to them due to the constraints of the Class / Object system in Java, which follows from defining classes as the only way to add new types in Java.
If a = ...0000101 (bin) = 5 (dec)
~a = ~...0000101(bin) = ...1111010(bin)
and Java uses "Two's complement" form to represent negative numbers so
~a = -6 (dec)
Now difference between Integer.toBinaryString(number) and Integer.toString(number, 2) for negative number is that
toBinaryString returns String in "Two's complement" form but
toString(number, 2) calculates binary form as if number was positive and add "minus" mark if argument was negative.
So toString(number, 2) for ~a = -6 will
calculate binary value for 6 -> 0000110,
trim leading zeros -> 110,
add minus mark -> -110.
101 in integer is actually represented as 00000000000000000000000000000101 negate this and you get 11111111111111111111111111111010 - this is -6.
The toString() method interprets its argument as a signed value.
To demonstrate binary operations its better to use Integer.toBinaryString(). It interprets its argument as unsigned, so that ~101 is output as 11111111111111111111111111111010.
If you want fewer bits of output you can mask the result with &.
Just to elaborate on Edwin's answer a bit - if you're looking to create a variable length mask to develop the bits of interest, you might want some helper functions:
/**
* Negate a number, specifying the bits of interest.
*
* Negating 52 with an interest of 6 would result in 11 (from 110100 to 001011).
* Negating 0 with an interest of 32 would result in -1 (equivalent to ~0).
*
* #param number the number to negate.
* #param bitsOfInterest the bits we're interested in limiting ourself to (32 maximum).
* #return the negated number.
*/
public int negate(int number, int bitsOfInterest) {
int negated = ~number;
int mask = ~0 >>> (32 - bitsOfInterest);
logger.info("Mask for negation is [" + Integer.toBinaryString(mask) + "]");
return negated & mask;
}
/**
* Negate a number, assuming we're interesting in negation of all 31 bits (exluding the sign).
*
* Negating 32 in this case would result in ({#link Integer#MAX_VALUE} - 32).
*
* #param number the number to negate.
* #return the negated number.
*/
public int negate(int number) {
return negate(number, 31);
}

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!

Categories