I am new to bytes and bits and I'm also not very good in maths either. I kind of understand the bitwise operators, but I don't know how to solve math equations/formulas with 2 variables. I'm not sure this is the proper place to ask this but anyway.
I have an formula like this:
(Adr_MSB & 0x3F) << (8 + Adr_LSB)
Now what I want is that I would get an integer (for example 33) and the code would transform it into Adr_MSB and Adr_LSB (which are bytes).
It should work up to 128 (ok I guess it will be 127).
I know that this question might sound dumb or something, but I just don't know enough maths to solve this.
Thanks for all help.
EDIT: By experimenting I figured out, that Adr_MSB is a multiplier (e.g. if it's 10 the result is 10 times biger than if it's 1).
From what I understand
the (Adr_MSB & 0x3F) part of the takes the last six bits of the Adr_MSB and returns corresponding integer.
Eg: 125 (1111101) will return 61 (111101)
Note: This step is removing all bits other than last 6 bits, these bits are lost. Hence Lossless inverse function is not possible.
The (8 + Adr_LSB) just adds 8 to Adr_LSB.
<< is a bit wise Left Shift Operator.
Eg. 61 << 3 = 488 . Since 61 is 111101, adding three zeros to the right (Left Shifting three times) will give 111101000 which is 488.
Effective inverse of the expression (Adr_MSB & 0x3F) << (8 + Adr_LSB) to be applied to given number x
Take first six bits from x and convert it to int. This will be Adr_MSB.
Count the rest of the bits. Subtract 8 from this count and it will be Adr_LSB.
Does the following represent what you are looking for?
((Adr_MSB & 0x3F) << 8) | Adr_LSB
Would this work?
int x = 33;
byte Adr_MSB = (byte)x;
byte Adr_LSB = (byte)24;
System.out.println((Adr_MSB & 0x3F) << (8 + Adr_LSB));
Adr_LSB can also be -8.
Since you do bitwise AND on Adr_MSB and 111111, you have only six consecutive bits available to represent the number, so not all integers can be represented just by shifting those 6 bits. This solution works for x up to , so... you can argue that is not a good solution, but it is a start.
Related
This question already has answers here:
How does bitshifting work in Java?
(10 answers)
Closed 2 years ago.
Actually I know the declaration of array in java but here I am unable to understand the use of this syntax:
int a[] = new int[3 << 1];
In place of a size for the array, here << this symbol is used for?
The << symbol is known as the "left shift operator." As you can probably guess, it gets its name from shifting bit positions to the left.
There's a good example posted by another user at the following:
How do shift operators work in Java?
Right shift and left shift operators shift your number to the right of left in their binary representation. If you left shift by one the number 3 3<<1 this would mean that:
The binary for 3 which is 011 gets shifted to the left(basically a 0 is added in the front) 0110 and now your number is 6.
The opposite thing would happen with right shift: If you have the number 3 011 and you right shift it by 1 3>>1 the first bit will get chopped off 01 and you'll end up with the number 1.
Shift operators are useful for multiplying or dividing by powers of 2, and it's a bit faster than just saying 3*2.
<< is the left shift operator and belongs to the bitwise and bit shift operators. For a detailed explanation of how each bitwise and bit shift operator works, please refer to this answer by #DerekPark. Thus, 3 << 1 is an arthmetic expression that gets evaluated before the array is created. 3 << 1 evaluates to 6, thus an int[] of size 6 gets created.
Ideone Demo
<< is the bitwise left shift operator and is often used for efficiently multiplying for specific powers of two, as bitwise operators tend to be faster. x << n is usually equivalent to x*2n, except for cases involving int overflow.
3 in binary is represented as 11 and after shifting to the left by one, it becomes 110, which is 6 in decimal. It can be seen intuitively that shifting by n places to the left is equivalent to multiplying by two n times, as each shift adds a binary digit to the right, which increases the value of every other digit by a factor of 2.
I recently learned a method in BigInteger Java class called
BigInteger.testBit(n)
Its main function is (this & (1<<n)) != 0), but I do not quite understand the source code
return (getInt(n >>> 5) & (1 << (n & 31))) != 0;
Can someone explain it?
I'm not familiar with how it's implemented, but judging by that code, I would assume that a BigInteger is implemented by storing it's value in a list of integers, and getInt(n) returns the n'th of these, where 0 = least significant.
The first will store the least significant 32 bits, getInt(1) will store bits 32-63 etc. By shifting n right by 5, you get the index of the integer in the internal list that has the bit you care about, it's the equivalent to n div 32.
With that integer, you then pick out the bit you care about from it with the (1 << (n & 31)). n & 31 is the equivalent of n modulo 32, and the 1 << is the equivalent of 2^. This gets you a bit mask that selects precisely the bit you care about.
I have an int, and I would like to get the 19 most significant bits in java. I tried all sorts of methods, none of them work.
Can someone please help me?
Adding to Bram's answer, you don't even need the AND if you use unsigned shift.
myInt >>> 13; will give you the 19MSB (although they're now situated in the lowest bits).
From the 32 bit int, you want to keep the 19 most significant, so discard the 13 least; then you shift right by 13 bits, but have to get rid of the possible sign extension, by anding with a 19 bit pattern:
(myint >> 13) & 0x7ffff
Integer is of 4 byte i.e. 4*8 = 32 bits. So if you want to get 19th bit, you may want to try something like:
if (myint & 0X00002000 >> 19 == 1) {
//do something
}
I have a 3 byte signed number that I need to determine the value of in Java. I believe it is signed with one's complement but I'm not 100% sure (I haven't studied this stuff in more than 10 years and the documentation of my problem isn't super clear). I think the problem I'm having is Java does everything in two's complement. I have a specific example to show:
The original 3-byte number: 0xEE1B17
Parsed as an integer (Integer.parseInt(s, 16)) this becomes: 15604503
If I do a simple bit flip (~) of this I get (I think) a two's complement representation: -15604504
But the value I should be getting is: -1172713
What I think is happening is I'm getting the two's complement of the entire int and not just the 3 bytes of the int, but I don't know how to fix this.
What I have been able to do is convert the integer to a binary string (Integer.toBinaryString()) and then manually "flip" all of the 0s to 1s and vice-versa. When then parsing this integer (Integer.parseInt(s, 16)) I get 1172712 which is very close. In all of the other examples I need to always add 1 to the result to get the answer.
Can anyone diagnose what type of signed number encoding is being used here and if there is a solution other than manually flipping every character of a string? I feel like there must be a much more elegant way to do this.
EDIT: All of the responders have helped in different ways, but my general question was how to flip a 3-byte number and #louis-wasserman answered this and answered first so I'm marking him as the solution. Thanks to everyone for the help!
If you want to flip the low three bytes of a Java int, then you just do ^ 0x00FFFFFF.
0xFFEE1B17 is -1172713
You must only add the leading byte. FF if the highest bit of the 3-byte value is set and 00 otherwise.
A method which converts your 3-byte value to a proper intcould look like this:
if(byte3val>7FFFFF)
return byte3val| 0xFF000000;
else
return byte3val;
Negative signed numbers are defined so that a + (-a) = 0. So it means that all bits are flipped and then 1 added. See Two's complement. You can check that the condition is satisfied by this process by thinking what happens when you add a + ~a + 1.
You can recognize that a number is negative by its most significant bit. So if you need to convert a signed 3-byte number into a 4-byte number, you can do it by checking the bit and if it's set, set also the bits of the fourth byte:
if ((a & 0x800000) != 0)
a = a | 0xff000000;
You can do it also in a single expression, which will most likely perform better, because there is no branching in the computation (branching doesn't play well with pipelining in current CPUs):
a = (0xfffffe << a) >> a;
Here << and >> perform byte shifts. First we shift the number 8 bits to the right (so now it occupies the 3 "upper" bytes instead of the 3 "lower" ones), and then shift it back. The trick is that >> is so-called Arithmetic shift also known as signed shift. copies the most significant bit to all bits that are made vacant by the operation. This is exactly to keep the sign of the number. Indeed:
(0x1ffffe << 8) >> 8 -> 2097150
(0xfffffe << 8) >> 8 -> -2
Just note that java also has a unsigned right shift operator >>>. For more information, see Java Tutorial: Bitwise and Bit Shift Operators.
So in Java, I have:
long value = 1324623451867855123L
I need the 36 least significant bits, the MOST significant bits can be thrown out. In my head, I could use bitwise and and just do
long rightMost36Bits = value & 0xFFFFFFFFFL
And that would give me the bottom 36 bits. But... not so worky. What am I missing?
Edit
Fixed typo, meant & for and.
Edit2
Really wanted bottom 10 decimal digits. So I should just use % 10000000000. Sorry for over engineering a solution :)
The result from that equation is 12444252435. That is not what I want. I want more like 451867855132
That should be value & 0xFFFFFFFFFL. You used ^ which is XOR.
^ is bitwise XOR. You want
value & 0xFFFFFFFFFL;
for bitwise AND to lose the higher order bits. XOR will leave the high-order bits alone while inverting the 36 low order bits. AND will set the high-order bits to zero and retain the low order bits.