How to calculate byte as 16 bits in Java - java

I have a value of 2 bytes. 9C 80
Among them
2 bits in the first byte are the mode values ​​as shown in the picture below,
The next 12bit is the number of steps.
This way, you have a total of 2 bytes.
But I don't know how to calculate it in 16 bits.
The result of extracting 12 bits using 9C 80 bytes is 114.
This is wrong.
The correct answer is 39 steps.
39 steps
Can it come out of the 12bit of the 9C 80?
Help.
Below is the bit position of the byte values ​​passed from c.
struct ble_sync_sport_item
{
uint16_t mode : 2;
uint16_t sport_count : 12;
uint16_t active_time : 4;
uint16_t calories : 10;
uint16_t distance : 12;
};
This is the android code I made to calculate the byte value.
private int bytesToInt(byte[] bytes , String value) {
int binaryToDecimal = 0;
int binaryToDecimal2 = 0;
int binaryToDecimal3 = 0;
int result = 0;
String s1 = "";
String s2 = "";
String s3 = "";
byteLog("5bytes ",bytes);
switch (value) {
case "ACT_STEP":
s1 = String.format("%8s", Integer.toBinaryString(bytes[0] & 0xFF)).replace(' ', '0');
s2 = String.format("%8s", Integer.toBinaryString(bytes[1] & 0xFF)).replace(' ', '0');
Log.d("FASDF ", "s1 == " + s1 + " s2 = " + s2 );
s1 = s1.substring(2, 8).concat(s2.substring(0,2));
s2 = s2.substring(2, 8).concat("00");
Log.d("FASDF ", "s1 == " + s1 + " s2 = " + s2 );
binaryToDecimal = Integer.parseInt(s1, 2);
binaryToDecimal2 = Integer.parseInt(s2, 2);
result = (int) ((int) binaryToDecimal) + ((int) binaryToDecimal2 << 8);
Log.d(tag,"result_step = " + result);
break;
This is the logarithm of the result I calculated.
39 should come out
114 came out.
As the result
The mode value of binary number 10 and
I want to get the sprot_count value of 100111 binary.
D/FASDF: s1 == 10011100 = 0x9C ,, s2 = 10000000 = 0x80
D/SevenHL5ConnectSync: result_step = 114

This could be an issue with bit order in the byte. Please check Big Endian vs Little Endian mode. The result you're getting 114 (1110010) is just the opposite of 39 (0100111) that is a reverse order in the bit.

Related

Can we pass a character as an index for integer array in java

I am new to java and practicing some programs.Can someone please explain me the following program at //line 10
public static void main(String[] args) {
String str1 = "xxyz";
String str2 = "yxzx";
System.out.println("Original strings: " + str1 + " " + str2);
System.out.println(stringPermutation(str1, str2));
}
public static void stringPermutation(String str1, String str2) {
int[] arr = new int[500];
for (int i = 0; i < str1.length(); i++) {
System.out.println(arr[(int) str1.charAt(i)] += 1); //line 10
}
}
it's displaying the below output :
Original strings: xxyz yxzx
1
2
1
1
Am trying to understand, how arr[(int) str1.charAt(i)]i.e, arr['x'] is possible.
Please help me understanding this.
When you initialise an empty integer array the initial value for each of the item is zero, there for each index of arr will contain 0
int[] arr = new int[500];
arr[0] = 0;
arr[1] = 0;
//...
arr[500] = 0;
The ASCII value for x is 120, y is 121 and z is 122, since the arr field contains 500 item then 120, 121 and 122 is in range.
In your loop you are adding 1 to each of the element. therefore in your str1 = "xxyz" when the first x is encounter 1 is added to index arr[120] so arr[120] becomes 1 and when x is encounter again 1 is added to the value which makes arr[120] becomes 2.
arr[(int) 'x'] += 1 //=> arr[120] + 1 = (0 + 1) = 1
arr[(int) 'x'] += 1 //=> arr[120] + 1 = (1 + 1) = 2
arr[(int) 'y'] += 1 //=> arr[121] + 1 = (0 + 1) = 1
arr[(int) 'z'] += 1 //=> arr[122] + 1 = (0 + 1) = 1
arr['x'] is possible because in java char data type is a single 16-bit integer and int is 32-bit signed integer.
Update:
In the continuation for the program the second loop on str2 is deducting one at the char index, if str2 is a permutation of str1 the value all the item in arr should reset to 0.
After the loop on str1. The values in the array are
arr[0] = 0
//...
arr[120] = 2 //arr['x']
arr[121] = 1 //arr['y']
arr[122] = 1 //arr['z']
//...
arr[500] = 0
When str2 = "yxzx"
arr[(int) 'y'] -= 1 //=> arr[121] - 1 = (1 - 1) = 0
arr[(int) 'x'] -= 1 //=> arr[120] - 1 = (2 - 1) = 1
arr[(int) 'z'] -= 1 //=> arr[122] - 1 = (1 - 1) = 0
arr[(int) 'x'] -= 1 //=> arr[120] - 1 = (1 + 1) = 0
After the loop on str2 the values will be reset to 0
arr[0] = 0
//...
arr[120] = 0 //arr['x']
arr[121] = 0 //arr['y']
arr[122] = 0 //arr['z']
//...
arr[500] = 0
Hence looping through all the array if all the values are zeros then str2 is a permutation of str1.
Because of ASCII value of x is 120, y is 121 and z is 122.
So, Now
arr[x] => arr[120] = 1
arr[x] => arr[120] = 2
arr[y] => arr[121] = 1
arr[z] => arr[122] = 1
Yes, you can. A char variable can hold any integer from 0 to 65,535. The value of a char literal is equal to an integer from the ASCII table.
public class Main {
public static void main(String[] args) {
char[] charArr = { '0', 'A', 'z' };
int[] anArr = new int[123];
// Initialize
for (int i = 1; i < 123; i++) {
anArr[i] = i * 10;
}
// Display
for (char c : charArr) {
System.out.print(anArr[c] + "\t");// Will display 480 650 1220
}
}
}
Explanation:
anArr['0'] = anArr[48] which has 48*10 stored in it
anArr['A'] = anArr[65] which has 65*10 stored in it
anArr['z'] = anArr[122] which has 122*10 stored in it

Need proof/breakdown of String.hashCode() method in java

I know that the formula adopted for the String.hashCode() method is as follows:
S0x31(n-1)+s1x31(n-2)+…+s(n-1)
In my textbook, I am given the example of the word Cat.
'C' x31^2 + 'a' x 31 +t
The final value is given as 67,510
I am utterly confused as to where this value was derived from, specifically, what values were used for the individual characters. I have tried 37, 66 and 85 (utilising the Unicode character for capital C, lower case a and t respectively). This was invalid. Can someone illumninate this for me?
Regrettably, this is the only example given by my textbook and there is no attempt to clarify or explain it.
67 * 31^2 + 97 * 31^1 + 116 * 31^0 =
67 * 31^2 + 97 * 31 + 116 =
64387 + 3007 + 116 =
67510
With 67, 97 and 116 taken from http://www.asciitable.com/
String hashCode does:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
So basically each iteration the existing hash is multiplied by 31, and then the next value is added to the hash.
so with 'C' = 67, 'a' = 97, 't' = 116 you get:
h = 0
h *= 31;
h += 67; // 'C'
h *= 31;
h += 97; // 'a'
h *= 31;
h += 116;
h ==> 67510

Get Bit values from Byte Array

I have a byte array from which I need to read specific bits and convert to int (see the byte array structure below). Even though the bits information I want to read is in 3 bytes, I tried reading 4 bytes (6-9) as integer and then read the bits from that integer value with bits or bitsValue method but somehow I am not able to see the right values from the bit manipulation. And with my expertise in bits I am pretty sure I am doing something wrong.
Can someone please suggest I am doing it correctly and why its not working. Thanks in Advance!!
Byte array is in Little Endian format.
0th byte - Some Value
1st Byte - Some Value
2nd - 5th Byte - Some Value
6th - 9th Byte - first 18 bits represent some value
- Next 5 bits represent some value
- Next 1 bit represent some value
- Last 8 bits represent some value
public class Test {
public static void main(String... dataProvider) {
String s = "46 00 ef 30 e9 08 cc a5 03 43";
byte[] bytes = new byte[s.length()];
bytes = hexStringToByteArray(s);
int bytePointer = 0;
int msgType = getIntFromSingleByte(bytes[bytePointer]); // 0th byte
int version = getIntFromSingleByte(bytes[++bytePointer]); // 1st byte
int tickInMS = getIntValue(bytes, ++bytePointer); // 2nd-5th bytes
bytePointer = bytePointer + 4;
int headr = getIntValue(bytes, bytePointer); // 6th-9th bytes
int utcTime = bits(headr, 0, 18); // 6th-9th bytes - 18 bits
int reserved = bits(headr, 18, 5); // 6th-9th bytes- 5 bits
int reportOrEvent = bits(headr, 23, 1); // 6th-9th bytes - 1 bits
int reportId = bitsValue(headr, 24, 32); // 6th-9th- 8 bits
}
public static int getIntFromSingleByte(byte data) {
return (data & 0xFF);
}
public static int getIntValue(byte[] bytes, int startPosition) {
byte[] dest = new byte[4];
System.arraycopy(bytes, startPosition, dest, 0, dest.length);
return toInt(dest);
}
// took from Stack overflow
static int bits(int n, int offset, int length) {
// shift the bits rightward, so that the desired chunk is at the right end
n = n >> (31 - offset - length);
// prepare a mask where only the rightmost `length` bits are 1's
int mask = ~(-1 << length);
// zero out all bits but the right chunk
return n & mask;
}
public static int bitsValue(int intNum, int startBitPos, int endBitPos) {
// parameters checking ignored for now
int tempValue = intNum << endBitPos;
return tempValue >> (startBitPos + endBitPos);
}
public static byte[] hexStringToByteArray(final String s) {
String[] splits = s.split(" ");
final byte[] data = new byte[splits.length];
for (int i = 0; i < splits.length; i++) {
char first = splits[i].length() < 2 ? '0' : splits[i].charAt(0);
char second = splits[i].length() < 2 ? splits[i].charAt(0) : splits[i].charAt(1);
data[i] = (byte) ((Character.digit(first, 16) << 4) + Character.digit(second, 16));
}
return data;
}
public static int toInt(byte[] data) {
if (data == null || data.length != 4)
return 0x0;
return (int) ((0xff & data[0]) << 24 | (0xff & data[1]) << 16 | (0xff & data[2]) << 8
| (0xff & data[3]) << 0);
}
}
Wrapping your input data in a ByteBuffer will simplify parsing and allow you to adjust endianness as necessary.
Your bits method is wrong. The constant 31 should be 32. Also, the method uses MSB 0 bit numbering, which is odd for little-endian data. You should confirm that your input is documented as using this bit numbering scheme.
Your bitsValue method is wrong too. May as well just use bits after fixing it.
This code is simpler and extracts the bit fields correctly:
public static void main(String... args) {
String s = "46 0 79 37 a8 3 9f 37 1 43 eb 7a f 3 3 fe c4 1 c5 4 c5 5e";
byte[] input = hexStringToByteArray(s);
// Wrap the input in a ByteBuffer for parsing. Adjust endianness if necessary.
ByteBuffer buffer = ByteBuffer.wrap(input).order(ByteOrder.BIG_ENDIAN);
int msgType = buffer.get() & 0xff;
int version = buffer.get() & 0xff;
int tickInMS = buffer.getInt();
int header = buffer.getInt();
int utcTime = bits(header, 0, 18); // 6th-9th bytes - 18 bits
int reserved = bits(header, 18, 5); // 6th-9th bytes - 5 bits
int reportOrEvent = bits(header, 23, 1); // 6th-9th bytes - 1 bit
int reportId = bits(header, 24, 8); // 6th-9th bytes - 8 bits
System.out.printf("utc: %d, report? %d, id: %d\n", utcTime, reportOrEvent, reportId);
}
/**
* Extract a bit field from an int. Bit numbering is MSB 0.
*/
public static int bits(int n, int offset, int length) {
return n >> (32 - offset - length) & ~(-1 << length);
}
Instead of error prone bit mangeling you should rather use the binary string representation of the numbers and do your "bit picking" as string operations:
String s = "46 00 ef 30 e9 08 cc a5 03 43";
String[] hexNumbers = s.split(" ");
for(String hexNumber : hexNumbers) {
String binaryNumber = String.format("%8s", new BigInteger(hexNumber,16).toString(2)).replace(' ','0');
System.out.print(String.format("value in hex : %s, value in binary: %s", hexNumber,binaryNumber));
}

Algorithm to solve unfinished equations in Java

I am trying to write a program that when given unfinished equations will output the lowest digit that will work or -1 if none will work. I have all my input set up but at this stage I am not sure how to continue.
Example inputs are: 1+1=?, 123*45?=5?088, -5?*-1=5, 19--45=5?, ??*??=302?
Any tips on how to tackle this would be appreciated.
import java.util.Scanner;
import java.util.regex.*;
public class Runes {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int caseNo = sc.nextInt();
for (int c = 0; c < caseNo; c++) {
String input = sc.next();
String re1="([-]?[0-9?]+)"; // -int1 or int1
String re2="([+\\-*])"; //+ or - or *
String re3="([-]?[0-9?]+)"; // -int2 or int2
String re4="(=)"; // Equals
String re5="([-]?[0-9?]+)"; // -int3 or int3
Pattern pattern = Pattern.compile(re1+re2+re3+re4+re5,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
String int1 = matcher.group(1);
String op1 = matcher.group(2);
String int2 = matcher.group(3);
String op2 = matcher.group(4);
String int3 = matcher.group(5);
System.out.println(int1 + " " + op1 + " " + int2 + " " + op2 + " " + int3);
}
}
}
}
Here's one way to create your Java application.
Create an Integer index array with a value for each question mark. In other words, if there are 5 question marks, your Integer index array has 5 elements.
Loop through the Integer index array. In other words, for 5 question marks, the values ought to be (see layout below).
Looping through the Integer index array, substitute the index values for the question marks.
Check to see if the string is a valid equation. If so, save it in a List.
When the looping is finished, print the List values.
Here's the layout for point 2.
0, 0, 0, 0, 0
1, 0, 0, 0, 0
...
9, 0, 0, 0, 0
0, 1, 0, 0, 0
...
9, 9, 9, 9, 9
I used your input examples to create this output. I added spaces to the equations to make them easier to read. I manually formatted this output to fit on the screen
1 + 1 = ? --> 1 + 1 = 2
123 * 45? = 5?088 --> 123 * 456 = 56088
-5? * -1 = 5 --> No equation exists
19 - -45 = 5? --> No equation exists
?? * ?? = 302? --> 57 * 53 = 3021 53 * 57 = 3021 72 * 42 = 3024
42 * 72 = 3024 48 * 63 = 3024 56 * 54 = 3024
36 * 84 = 3024 84 * 36 = 3024 54 * 56 = 3024
63 * 48 = 3024 55 * 55 = 3025 89 * 34 = 3026
34 * 89 = 3026

Java stripping zeros from function

I'm trying to flip some bytes around in Java and the function I have is working correctly for some bytes and failing for others.
The function I am using is this:
public static int foldInByte(int m, int pos, byte b) {
int tempInt = (b << (pos * 8));
tempInt = tempInt & (0x000000ff << (pos * 8));
m = m | tempInt;
return m;
}
And the code that implements this is:
byte[] bitMaskArray = new byte[]{
byteBuffer.get(inputIndex),
byteBuffer.get(inputIndex + 1),
byteBuffer.get(inputIndex + 2),
byteBuffer.get(inputIndex + 3)};
int tempInt = 0;
tempInt = foldInByte(0, 3, bitMaskArray[3]);
tempInt = foldInByte(tempInt, 2, bitMaskArray[2]);
tempInt = foldInByte(tempInt, 1, bitMaskArray[1]);
tempInt = foldInByte(tempInt, 0, bitMaskArray[0]);
bitMask = tempInt;
The bytes are being read from a ByteBuffer with the byteOrder being Little Endian.
For example, the bytes 00 01 B6 02 set the bitMask to: 2B60100 - which works perfectly in my program.
However, if the bytes are A0 01 30 00, the bitMask is set to: 3001A0 - which has stipped the last zero from the bitmask.
Is there any way I can stop Java from stipping off trailing zeros?
I hope that makes sense.
Thanks
Tony
The zeros are not being stripped -- both examples cited are correct.
00 01 B6 02 is the 4-byte little-endian for 2B60100
A0 01 30 00 is the 4-byte little-endian for 3001A0
The zeros are there, but probably just not being printed. The System.out.print family of calls will not print leading zero digits.
I might mention that your method is needlessly complex. Here is a single method that computes the same value:
static int extractLittleEndian4(byte[] buf, int index)
{
int a = buf[index+0]&0xff, b = buf[index+1]&0xff, c = buf[index+2]&0xff, d = buf[index+3]&0xff;
return a | (b << 8) | (c << 16) | (d << 24);
}
It looks like you have a ByteBuffer filled with your bytes already. Why don't you let the ByteBuffer reverse the bytes for you? Just add the bytes to the buffer (BIG_ENDIAN is the default if you want to add an integer instead of bytes) and then change the order before reading the integer.
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
int output = byteBuffer.getInt(0);
If all you're doing is reversing the byte order, let the library do the work for you. If you happened to start with an integer value, you can even just do this:
int input = ...;
int output = Integer.reverseBytes(input);

Categories