I am converting 4 integers into binary and everything works fine until it has to convert a zero.
for example:
int subnet1 = 255;
int subnet2 = 255;
int subnet3 = 255;
int subnet4 = 0;
binarystring = Integer.toBinaryString(subnet1)
+ Integer.toBinaryString(subnet2)
+ Integer.toBinaryString(subnet3)
+ Integer.toBinaryString(subnet4);
BinaryView.setText(binarystring);
text would look like this: 11111111 11111111 11111111 0 (without the space inbetween)
why wont it convert the 0 to 00000000 ??
Because value for "0000000" is same for "0" that's why it set as "0".
If you want to print that result. Just make a string of "0000000" for printing. Because int value always convert it.
Why? By design. From the documentation:
This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0s.
(Emphasis added.)
If you want 8 characters, append the result to a string of 7 zeros, and take the last 8 characters. In pseudo code:
intermediateString = "0000000" + Integer.toBinaryString( 0 ); // obviously don't hard code zero; just for example
finalString = intermediateString.substring( intermediateString.length() - 8);
If you read the documentation here: https://developer.android.com/reference/java/lang/Integer.html#toBinaryString(int)
It tells you:
The unsigned integer value is the argument plus 232 if the argument is negative; otherwise it is equal to the argument. This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0s.
Related
I am newbie on Matlab, and i am trying to plot the data from the txt file written by an android application ( https://play.google.com/store/apps/details?id=com.lul.accelerometer&hl=it)
I cleaned the file and i have only the 4 columns with values separated by the " "
X Y Z time_from_previous_sample(ms)
e.g.
-1.413 6.572 6.975 0
-1.2 6.505 7.229 5
-1.047 6.341 7.26 5
-1.024 6.305 7.295 5
-1.154 6.318 7.247 5
-1.118 6.444 7.104 5
-1.049 6.225 7.173 5
-1.098 6.063 6.939 5
-0.769 6.53 6.903 5
fileID = fopen ('provamatlav.txt');
C = textscan (fileID, '%s %s %s %s');
fclose (fileID);
>> celldisp (C)`
After importing the data i created three new variables
X = C {1};
Y = C {2};
Z= C {3}
The error occur when i try to convert the cell array X into an ordinary array
xx = cell2mat('X')
the error is the following
Cell contents reference from a non-cell array object.
Error in cell2mat (line 36)
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
Analyzing the code:
% Copyright 1984-2010 The MathWorks, Inc.
% Error out if there is no input argument
if nargin==0
error(message('MATLAB:cell2mat:NoInputs'));
end
% short circuit for simplest case
elements = numel(c);
if elements == 0
m = [];
return
end
if elements == 1
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
m = c{1};
return
end
end
% Error out if cell array contains mixed data types
cellclass = class(c{1});
ciscellclass = cellfun('isclass',c,cellclass);
if ~all(ciscellclass(:))
error(message('MATLAB:cell2mat:MixedDataTypes'));
end
What did i do wrong?
After solved this, what would be the next step to plot the X Y Z data in the same window, but in separate graphs?
Thank you so much!
When using cell2mat, you do not need to use quotes when giving the input argument. The quotes are the reason for the error you got. Generally speaking, you would call it like so:
xx = cell2mat(X)
But you will run into a different error with this in your code, because the cell elements in your case are strings (cell2mat expects numerical values as the output). So you need to convert them to numerical format, e.g. by using this:
xx=cellfun(#str2num,X)
Please try the code line above. It worked ok in my small test case.
I am currently working on a Android application that takes values from a text box and then sends it over bluetooth, all operations are in Hex values.
I have a convertion method that can take the string make give me the unsigned integer for the string, but once i place it in the byte array it becomes signed and the board that receives this cannot do signed hex.
This is how the process works:
//sample string to send
String toSend = "0BDD";
//sending the byte[] to the board over bluetooth
btOutputStream.write(SendByteData(toSend));
// --- perform the conversion to byte[] ---
public static byte[] SendByteData(String hexString)
{
byte[] sendingThisByteArray = new byte[hexString.length()/2];
int count = 0;
for( int i = 0; i < hexString.length() - 1; i += 2 )
{
//grab the hex in pairs
String output = hexString.substring(i, (i + 2));
//convert the 2 characters in the 'output' string to the hex number
int decimal = (int)(Integer.parseInt(output, 16)) ;
//place into array for sending
sendingThisByteArray[count] = (byte)(decimal);
Log.d(TAG, "in byte array = " + sendingThisByteArray[count]);
count ++;
}
return sendingThisByteArray;
}
The issue is as follows:
When the for for loop runs through the string and picks up "0B" it correctly gives me integer 11; then when the loop runs through "DD" it give me integer 221 which is also correct
When I perform the operation of
sendingThisByteArray[count] = (byte)(decimal);
11 gets correctly placed in sendingThisByteArray[0]
but for sendingThisByteArray[1] the number 221 gets changed to -35
I know that Java has signed bytes.. is there a way to put/place/change the byte array so i can place and number 221 or any other value higher than 127?
your help is greatly appreciated
You can convert from a signed integer to unsigned byte like this, by binary AND'ing it with 0xFF:
sendingThisByteArray[count] = (byte)(decimal & 0xFF);
This way you can send values from 0 to 255
I found the problem, when i tried to do unsigned hex into a byte array it would always put a sign, i had to create single byte to retain the unsigned hex
int zeroA = (int)(Integer.parseInt("0D", 16));
sendStream.write(unsignedToBytes((byte) zeroA));
I am getting response from server in string format like
V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D410240x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101
Then I am converting it in to byte array because i need to get value from this byte by byte.
I tried to use
Arrays.copyOfRange(original,
from , to);
but it work on index basis not on byte basis.
I also tried following solution but it also truncating String(if I use string instead of byte[]) on length basis.
public static String truncateWhenUTF8(String s, int maxBytes) {
int b = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// ranges from http://en.wikipedia.org/wiki/UTF-8
int skip = 0;
int more;
if (c <= 0x007f) {
more = 1;
} else if (c <= 0x07FF) {
more = 2;
} else if (c <= 0xd7ff) {
more = 3;
} else if (c <= 0xDFFF) {
// surrogate area, consume next char as well
more = 4;
skip = 1;
} else {
more = 3;
}
if (b + more > maxBytes) {
return s.substring(0, i);
}
b += more;
i += skip;
}
return s;
}
I know how to calculate string in byte length but it giving only full string length in byte like
Here is how I need to extract packet on byte basis.
Above codes and parameters is only example. I need to get byte by byte from string/byte array.
I searched lot but didn't get any solution or link which I can refer. I am not getting how to split string using byte length because I know byte length for each parameter and for value also.
Please give me any reference or hint.
To determine what is equal to one byte in a String is not trivial. Your String contains bytes in hexadecimal text form: 0x0D (one byte, equal to 13), but also contains values as substrings. For example 1024 can be interpreted as an integer which in this case fits into 2 bytes, but could also be interpreted as a text made up by 4 chars, totaling to 8 bytes.
Anyways, I would split the string using a regular expression, and then further split the parts to length and value:
String message = "V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D41024"+
"0x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101";
String regex = "(0)(x)(\\w\\w)";
String[] parts = message.split(regex);
Log.d(TAG,"HEADER = "+parts[0]);
for (int i=1; i<parts.length; i++) {
String s = parts[i];
// Only process if it has length > 0
if (s.length()>0) {
String len = "", val = "";
// String s is now in format LVVVV where L is the length, V is the value
if (s.length() < 11) {
// 1 character indicates length, up to 9 contains value
len = s.substring(0, 1);
val = s.substring(1);
} else if (s.length() > 10) {
// 2 characters indicate length, up to 99 contains value
len = s.substring(0, 2);
val = s.substring(2);
} else if (s.length() > 101) {
// 3 characters indicate length, up to 999 contains value
len = s.substring(0, 3);
val = s.substring(3);
}
Log.d(TAG, "Length: " + len + " Value: " + val);
}
}
This produces the following output:
D/Activity: HEADER = V1YYZZ
D/Activity: Length: 0 Value: 001
D/Activity: Length: 1 Value: 1205
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 21 Value: TATADOCOMOINTERNET101
Then you can check the packages (the first two package in the header is not needed), convert Strings to whatever you would like (e.g. Integer.parseInt(val))
If you explain the structure of the header (V1YYZZ0x0000010x0D0x0011205), I can improve my answer to find the message count.
I think it is doable with Scanner
import java.util.Scanner;
public class Library {
public static void main(String[] args) {
String s = "V1YYZZ0x0000010x0D0x001120"
+ "50x0C152031962061900x0D410240x0E152031962061900x0F410240x1"
+ "021TATADOCOMOINTERNET101";
// Skip first 9? bytes. I'm not sure how you define them
// so I just assumed it is 26 chars long.
s = s.substring(26, s.length());
System.out.println(s);
Scanner scanner = new Scanner(s);
// Use byte as delimiter i.e. 0xDC, 0x00
// Maybe you should use smth like 0x[\\da-fA-F]{2}
// And if you want to know that byte, you should use
// just 0x and get first 2 chars later
scanner.useDelimiter("0x\\w{2}");
// Easily extracted
int numberOfParams = scanner.nextInt();
for (int i = 0; i < numberOfParams; i++) {
String extracted = scanner.next();
// Length of message
int l = extracted.length();
boolean c = getLength(l) == getLength(l - getLength(l));
l -= getLength(l);
l = c ? l : l-1;
System.out.println("length="
+ extracted.substring(0, extracted.length()-l));
System.out.println("message="
+ extracted.substring(extracted.length()-l, extracted.length()));
}
// close the scanner
scanner.close();
}
// Counting digits assuming number is decimal
private static int getLength(int l) {
int length = (int) (Math.log10(l) + 1);
System.out.println("counted length = " + length);
return length;
}
}
We definitely need more information about rules, how string is formed. And what exactly you need to do. This code might be good enough you. And without comments it is really short and simple.
This is not a answer to accessing a byte array byte by byte, but is an answer for the situation in which you find yourself.
Your explanation and description have the appearance of being confused as to what it is that you are really getting from the server (e.g. it is quite hard to represent "V1YYZZ0x0000010x0D0x001120" as a 9 byte field (note it probably ends on the 2, not the 0)). Alternately, that you are using the wrong method to get it from the server, or not getting it as the intended data type.
Your code indicates that you believe that what you are getting is a UTF8 string. The data shown in your question does not appear to indicate that it is intended to be in that format.
Keep in mind when doing something like this that some other programmer had to create structure for the data that you are seeing. They had to define it somewhere with the intent that it be able to be decoded by their intended recipients. Unless there are other considerations (security, minimal bandwidth, etc.), such formats are usually defined in a way that is both easy to encode and decode.
The existence of the multiple "0x"-ASCII-encoded hexadecimal numbers --particularly the single byte representing the parameter (called "varam" in your graphic)-- strongly implies that this data was intended to be interpreted as a ASCII encoded string. While that might not be the case, it should be kept in mind when looking at the problem from a larger perspective.
You are having to put too much effort into decoding the information you are getting from the server. It, probably, should be relatively easy unless there are considerations why it would have intentionally been made difficult.
All of this indicates that the real problem exists in an area for which you have provided us with no information.
Step back:
Think about things like:
How are you receiving this from the server (what function/interface)?
In the call requesting the information from the server is there a way to specify the encoding type be bytes, an ASCII string, or some other format that is easier to deal with than UTF8? At a minimum, it appears to be clear that the data was not intended to be handled as a UTF8 string. There should be a way for you to get it without it having been converted to UTF8.
Also, you should try to find an actual specification for the format of the data. You have not explained much about the source, so it may be you are reverse-engineering something and have no access to specifications.
Basically, it looks like this is a problem where it might be a good idea to step back and ask if you are starting from the point that makes it easiest to solve and if you are headed in the right direction for doing so.
I'm sure I'm missing something obvious...
String.getBytes();
And if you want to process it in order taking defined objects from the array, just wrap using
ByteBuffer.wrap();
The result being something along the lines of:
String s = "OUTPUT FROM SERVER";
byte[] bytes = s.getBytes();
ByteBuffer bb = ByteBuffer.wrap(bytes);
What did I miss from the initial question? :/
Im getting an Hour value from a database which I am working and I can't change it.
The value can be for example "1800" which means "18:00" or "930" which means "9:30". This value appears on a EditText.
So how can I insert the ":" in that value before it shows in the EditText.
Thanks!
According to the format you provided, the last two characters must be minute, so you can substring it and add the ":" in the middle.
String str = "1800";
final int len = str.length();
String formattedStr = str.substring(0, len - 2) + ":" + str.substring(len - 2, len); // 18:00
You can also use setText[] with the character[] attribute
char[] your_addition = {':'};
//use setText(char[], int start, int length)
your_editext.setText(your_addition, 2, 1);
You can also check the length of your string to make sure that the value for int start is correct using 2 when the length is 4 and 1 when the length is 3.
Hope this helps
try to split your string which is getting set to edit text. use yourString.split(":");
I am currently making an android application which accepts bluetooth measurement from a device. The way the data is packaged is in 4 bytes. I need to get two values out of these bytes.
First value is made up of: 6bit and 7bit of first byte and bit 0 to bit 6 of byte 2
Second values is simpler and consists of the full 3rd byte.
What is a good way to access these bit values, combine them and convert them to integer values? Right now i'm trying to convert from byte array to bitset, and then access individual bits to create new bytes that would then be converted to a integer.
Thanks, and please ask if I am not being clear enough.
I figured it out: I converted the byte array to int using this method
public static int byteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i + offset] & 0x000000FF) << shift;
}
return value;
}
Then I used the method pokey described. Thanks for your help!
im not sure if i understood your format correctly.
Does this bitmask correspond to your first value?
0xC07F0000
That is bits 16-22,30,31 (zero based indexing used here, i.e. bit 31 is last bit).
Another thing, is your value expected to be signed or unsigned?
Anyway, if it is the way i assume then you can convert it like this with some bitmasks:
unsigned int val = 0xdeadbeef;
unsigned int mask1 = 0xC0000000;
unsigned int mask2 = 0x007F0000;
unsigned int YourValue = (val&mask1)>>23 | (val&mask2)>>16;
Do that in the same way with your other values. Define a bitmask and shift it to the right. Done.
Cheers