Parsing trouble! Bug in logic - java

I have a small bug here somewhere in my code! I must be blind because i really can't seem to find it or figure it out. I have a list of byte arrays. I'm parsing out the first 2 elements as well as the very last element in each array. If i get the value -16, -11 or -7 i want to keep the values. For some reason, the last value in on of the arrays is not being deleted. Why is this happening?

Have you tried debugging it?
When you have b = -110
it passed this condition:
if(b!= -15 && i + 2 < srec.length() && (Character.digit(srec.charAt(i + 2), 16) << 4) + Character.digit(srec.charAt(i + 3), 16) != -15
&& (Character.digit(srec.charAt(i + 2), 16) << 4) + Character.digit(srec.charAt(i + 3), 16) != -11)
b != 15 -> true
i + 2 = 124 < srec.length() = 142 -> true
(Character.digit(srec.charAt(i + 2), 16) << 4)+ Character.digit(srec.charAt(i + 3), 16) = -7 and -7 != -15 and also -7 != -11
hence the data.add(b) is executed.

Related

Java bits to Integer

I have an application that is sending me 2 shorts one increments from 0 -> 32 -> 48 -> 16 then back to 0 and the second increments each time the first one hits 0. The second one goes up to a maximum of 65535 and then loops round back to 0. I'm guessing this is some bits that are encoded which can be made to create a single number?
How can I combine these two shorts into a single number that increments by 1 if they increment in the behaviour described above?
0b0000_0000 0
0b0010_0000 32
0b0011_0000 48
0b0001_0000 16
So you can increment a counter modulo 4, 0, 1, 2, 3, 0, 1, 2, ... and switch the two bits. Modulo 4 means & 0b11.
int x = 0;
for (int i = 0; i < 100; ++i) {
System.out.printf("%04x%n", x);
x = (x + 1) & 0xFFFF;
x |= (x & 2) << 16;
x |= ~((x & 2) ^ (x & 1)) << 17; // Or something like that
}
I leave it to you to find the logic.

How to interpret hex number byte array from left shift binary sum?

My android application is receiving an array of data bytes that is sent from a C# application. I need to interpret those bytes.
In C# application, there are 16 check boxes (Bit0 to Bit15) in form and the code shows processing of those checkbox result.
ushort flag = (ushort)(
(Bit0.Checked ? (1 << 0) : (0)) +
(Bit1.Checked ? (1 << 1) : (0)) +
(Bit2.Checked ? (1 << 2) : (0)) +
(Bit3.Checked ? (1 << 3) : (0)) +
(Bit4.Checked ? (1 << 4) : (0)) +
(Bit5.Checked ? (1 << 5) : (0)) +
(Bit6.Checked ? (1 << 6) : (0)) +
(Bit7.Checked ? (1 << 7) : (0)) +
(Bit8.Checked ? (1 << 8) : (0)) +
(Bit9.Checked ? (1 << 9) : (0)) +
(Bit10.Checked ? (1 << 10) : (0)) +
(Bit11.Checked ? (1 << 11) : (0)) +
(Bit12.Checked ? (1 << 12) : (0)) +
(Bit13.Checked ? (1 << 13) : (0)) +
(Bit14.Checked ? (1 << 14) : (0)) +
(Bit15.Checked ? (1 << 15) : (0)));
flag is passed to the function described below and then it is sent to my Android application.
public static void setFlag(List<Byte> data, ushort flag)
{
for (int i = 0; i < 2; i++)
{
int t = flag >> (i * 8);
data.Add((byte)(t & 0x00FF));
}
}
In Android application, the data is received as an array of 4 bytes and then it is converted to decimal
public String bytesToAscii(byte[] data) {
String str = new String(data);
return str.trim();
}
// This returns the decimal
Integer.parseInt(bytesToAscii(flag), 16)
Let's say for example, when Bit13 was checked in the C# application; the Andriod app receives an array of 4 bytes which represents hex numbers:
flag[0] = 0x30;
flag[1] = 0x30;
flag[2] = 0x32;
flag[3] = 0x30;
It is converted to 0020 and it is then converted to decimal:
Integer.parseInt(bytesToAscii(flag), 16); // 32
I need to parse 32 to figure out Bit13 was selected. Bit13 is just an example for 32. I need to figure out which one or more Bit (0 to 15) are selected.
To check if a bit is set, you can do a bitwise AND with that bit. Then check if the result is equal to 0. If it isn't, the bit was set.
e.g.
00100110
00000010 // checks the second bit
-------- &
00000010 // result != 0, so the bit was set
A char is unsigned 16 bits, so you could use that to store the result.
0020 is almost right, but the bytes are reversed (00 20, should be 20 00 for Bit13).
byte[] flag = new byte[4];
flag[0] = 0x30;
flag[1] = 0x30;
flag[2] = 0x32;
flag[3] = 0x30;
// Bytes to char, using the 'oversized' short so the numbers won't be out of range
short b1 = Short.parseShort(new String(new byte[]{flag[0], flag[1]}), 16);
short b2 = Short.parseShort(new String(new byte[]{flag[2], flag[3]}), 16);
char i = (char) (b1 | (b2 << 8));
// Print contents as binary string
System.out.println(String.format("%16s", Integer.toBinaryString(i)).replace(' ', '0'));
// Output: 0010000000000000
// Check if 14'th bit is set (at index 13)
boolean isSet = ((i & (1 << 13)) != 0);
System.out.println(isSet); // true
You can use that method to check each bit. Just replace the 13 with the index you want to check.
I'm using a char here since that will print a little nicer. You could use a short, but whenever you convert that to an int (which can happen implicitly), the value gets padded with 1's if the most significant bit was set, because it's a signed type. char is unsigned however, so it doesn't have that behaviour.

Can I bit shift 0 to the beginning?

I'm trying to learn bit shifting/masking. Here is my code:
int health = 511; // max 512, 9 bits
int aimAngle = 510; // max 512, 9 bits
int test = 511; // max 512, 9 bits
boolean bool = false; // max 1, 1 bit
int packed;
packed = health | aimAngle << 9 | test << 18 | (bool?1:0) << 19;
Debug.log("health: " + ((packed ) & 0b111111111));
Debug.log("aimAngle: " + ((packed >> 9) & 0b111111111));
Debug.log("test: " + ((packed >> 18) & 0b111111111));
Debug.log("bool: " + ((packed >> 19) & 0b1));
I'm getting all the values correctly except bool. It's always 1. What is wrong? Can't I shift zero to the beginning?
test is up to nine bits long. You shift it right 18 places. Therefore it occupies bits 18 to 27. You need to shift bool to place 28 to avoid it, not to place 19.
The 19th digit of packed is the second digit of test, which is a 1.

Java Loop to go Through Numbers and Adding 5

I am writing Java code that needs to print these numbers: "0 5 10 3 8 1 6 11 4 9 2 7" in that order. I am new to Java, and am not very good at Loops yet. I am finding the points of a 12 point star, starting at 0, and trying to find the points that need to be touched by a line to make the star..
How do I do a loop that starts at 0, and adds 5 to each number.. so 0 + 5 = 5, 5+5=10, 10+5=3 (this is where my problem is.. How do I make it go back from 11 to 0?
I know this might seem confusing... or it might be extremely easy.. but any help would be greatly appreciated.
Increment by 5 until you pass 60, display the result of modulo 12. Something like,
for (int i = 0; i < 60; i += 5) {
System.out.println(i % 12);
}
This is called modulus, and java has the modulo operator % which gives the remainder of integer division.
15 / 12 == 1
15 % 12 == 3
as
(15 / 12) * 12 + (15 % 12) == 15
See the wikipedia.
Of course in your case you could also do
n += 5;
if (n >= 12) {
n -= 12;
}
instead of using modulo:
n = (n + 5) % 12;
Just iterate from 0 to 12, multiplying your number by 5, and applying modulus 12:
for (int i = 0; i < 12; i++) {
System.out.println(i * 5 % 12);
}
I believe the operator you are looking for is the modulus operator. The modulus gives you the remainder from a division problem. In this case you are using 12 as the denominator.
0 + 5 % 12 = 5 (0, remainder 5)
5 + 5 % 12 = 10 (0, remainder 10)
10 + 5 % 12 = 3 (1, remainder 3)
15 + 5 % 12 = 8 (1, remainder 8)
20 + 5 % 12 = 1 (2, remainder 1)
try this :
for(int i=0; ; i = (i+5)%12){
System.out.println(i);
if(i==7)break;
}

Shift operator in Java bizarre program output

I came across the following program and it behaving in unexpected manner.
public class ShiftProgram
{
public static void main(String[] args)
{
int i = 0;
while(-1 << i != 0)
i++;
System.out.println(i);
}
}
If we think about this program output, when it reaches 32 while loop condition should return false and terminate and it should print 32.
If you ran this program, it does not print anything but goes into an infinite loop. Any idea whats going on? Thank you in advance.
Have you tried printing out (-1 << i) in the loop to see what's going wrong? If you do, you'll see that it goes:
-1 << 0 = -1
-1 << 1 = -2
-1 << 2 = -4
-1 << 3 = -8
-1 << 4 = -16
-1 << 5 = -32
-1 << 6 = -64
-1 << 7 = -128
-1 << 8 = -256
-1 << 9 = -512
-1 << 10 = -1024
-1 << 11 = -2048
-1 << 12 = -4096
-1 << 13 = -8192
-1 << 14 = -16384
-1 << 15 = -32768
-1 << 16 = -65536
-1 << 17 = -131072
-1 << 18 = -262144
-1 << 19 = -524288
-1 << 20 = -1048576
-1 << 21 = -2097152
-1 << 22 = -4194304
-1 << 23 = -8388608
-1 << 24 = -16777216
-1 << 25 = -33554432
-1 << 26 = -67108864
-1 << 27 = -134217728
-1 << 28 = -268435456
-1 << 29 = -536870912
-1 << 30 = -1073741824
-1 << 31 = -2147483648
-1 << 32 = -1
-1 << 33 = -2
-1 << 34 = -4
-1 << 35 = -8
-1 << 36 = -16
[.. etc ..]
According to the language specification:
The value of n<<s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.
... so the result will always remain negative.
That document also tells you that:
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (ยง15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.
So if you use a shift of 32, that's interpreted as a shift of 32 & 0x1f, which is 0. -1 shifted by 0 is still just -1, not 0.
The shift count is interpreted modulo the number of bits in an int (32), and so i << 32 is just i << 0 which is i. Thus, you will never get 0 as the result. My source for that is http://www.janeg.ca/scjp/oper/shift.html. If you do something like int n = -1; while (n != 0) {i++; n <<= 1;}, it will eventually reach 0 like you want.

Categories