Convert string to float occurs NaN error in Processing - java

I meet a problem in the Processing, and when i convert the value(string) into float, the first value is good, but the rests are all NaN. I could not find a way to solve this. And i print the string value for test. And it is correct, but after i convert it into float. It will be NaN.
ps: the value is from the serial, i connected my Arduino with Proceesing.
following is a part of codes
while(myport.available() > 0)
{
myString = myport.readString(); //read the string from serial
num = float(myString); // convert the string into float
print(num); // print the num(float), but the first
// value is good, rests are all `NaN` .
//print(myString); // print string, all the values are good
print(' ');
if(myString != null)
{
//num = float(myString);
storeData(myString);
//println(myString);
//print(data[i - 1]);
//println(' ');
delay(1000);
}
}
following is the result
conversion finshed:
not convert, only print string value
following is arduino code
sum = sqrt(Xg*Xg + Yg*Yg + Zg * Zg);
sum *= 10;
sum = (map(sum, 0, 1024, 0, 5000)/10.0);
Serial.println(sum);
delay(100);

I think that the problem is not inside Arduino but inside the Processing code.
I was looking a lot and I note that there is an error that can most likely solve your problem.
You used val = myport.readString(); instead of val = myport.readStringUntil('\n'); .
The differences are few, but in your case would be substantial.
Take a look at ReadString function and ReadStringUntil function.
Anyway, it is also suggested by the sparkFun tutorial.
P.S. Of course, in your Arduino code, you have to use (well, like you were doing) Serial.println(sum); instead of Serial.print(sum) because, in the last case, that would not send to processing nothing before a line feed has been sended.

I find my problem is inside the Arduino code, so i changed the way to send the data from Arduino. I used the println() to send the data. And that's the point lead to NaN. I serached on google, and then i tested different ways to change the way to send until i finded this link:http://www.varesano.net/blog/fabio/sending-float-variables-over-serial-without-loss-precision-arduino-and-processing
And thanks fabio's blog, his blog's introudces a good way to solve this problem. If you have the same trouble, maybe you can fixed by this.

Related

Aproximation of log(10^k)

I am trying to find the result of log(10^k) , where k is big number like 10000. For example :
BigDecimal first = BigDecimal.TEN.pow(10000);
double result = Math.log(first.doubleValue());
However "result" becomes Infinity , however on wolphram approximates it to 23025.85.Any suggestion how to find the result? As a result the number with the first two digits after the decimal point are enough for me.
Use the fact that
log(10^k) = k*log(10)
So:
System.out.println(10000 * Math.log(10));
Prints:
23025.850929940458
The problem you are likely having, is that Wolphram is able to either hold the powered value or it is doing the log operation first.
When running this like your example, you will have an extremely large number that goes past the maximum value for a BigDecimal, which should result in an error or an "infinity", because it overflows the capability of the data type, I would suggest doing the operation the other way arround, perhaphs process the log first on a base 1 value for example and only then multiply it by whatever powered number you are tying to use.
See, there is a simple property of logarithms that you can use:
log(x^y) = y*log(x)
So what you can do is:
double y = y*log(x);
System.out.println(Math.round(y));
Hope this helps!

Parsing of math expression gives wrong tree

So the code is rather complicated so ill try to do some neat pseudo code that covers the most important issues. I'm trying to parse a math expression. For example: 1-5*(-2)+3 = 14
The syntax that im using is:
expression = term OR term+expression OR term-expression
term = factor OR factor*term OR factor/term
factor = number OR -factor OR (expression)
I have written a piece of code which checks if an expression follows this syntax and it works well for checking the expressions but not for calculating it.
The pseudo code goes something like:
double readExpression()
number = readTerm()
if token == +
number2 = readExpression()
return number + number2
else if token == -
number2 = readExpression()
return number - number2
else
return number
...
(The code for readTerm() is identical to readExpression() in structure)
...
double readFactor()
if token == number
return number
else if token == -
number = readFactor()
return (-1)*number
else if token == (
number = readExpression()
return number
else raise exception
If I do the above calculation with this code it will give me a tree that looks like this:
So anyway, as you matematicians have figured out byt now, the expression should give 14 and not 8 as the tree suggests. I have noticed the that the problem arises when there are minus-signs in front of expressions since affect the whole right term i this problem whilst they should only affect the middle-term.
Ive been thinking like crazy for weeks and thought about solutions for this and looked at other codes and so on. Please dont toss a bunch of links on me if they are not really really simple and good since ive been browsing alot myself on tree traversals and other relevant topics.
What could i do at this stage? As I said, my program can tell if its right or wrong. So now I only need to parse a correct expression. Should I write another class for the parsing of the correct expression? Is it easier? Anyway I dont see how that code would look different than this.
Yes I would parse the equation, it just looks like you miss a key part of the order of operations/parsing. You need to include an additional check for double negatives.
The key factor here is that: In a situation with two identical operators then the left most operation is always carried out first.
First lets narrow down the issue.
This 1-5*(-2)+3 is equal to 1--10+3.
Now for our purposes lets assign a positive to the first operator because it helps illustrate a point:
1--10+3 is the same as +1--10+3
Now if we where to run +1--10+3 through a correct parser we would know that this -- is equal to + but only when used in the following situation:
+X--Y = X+Y
So now our parser has turned the original expression of 1--10+3 into 1+10+3 and we know that is equal to 14.
So all up: Yes you need a parser, but pay special attention to how +X--Y and X+Y work.
Also take a look at this answer: https://stackoverflow.com/a/26227947/1270000

Converting from Int to Hex doesnt work in Java

int diny6h = Integer.parseInt(Integer.valueOf(diny6).toString(), 10);
int diny7h = Integer.parseInt(Integer.valueOf(diny7).toString(), 10);
diny6h=diny6h-32;
diny7h=diny7h-32;
System.out.println(diny6h + " + " + diny7h);
}
Incoming: diny6=30 diny7=20
printed: diny6h=16 diny7h=00
What i want: diny6h=10 diny7h=00
What am i doing wrong here?
EDIT:
well.. the numbers are send as hexadezimals and received as decimals, because the other numbers in the block (not diny6 and 7, but diny1 to diny5) are needed as hexadezimals. but diny6 and 7 are needed as decimals but im not able to get them the way i want i want to send a 35(hex) it comes in as 53(dec) and should be pirnted out as 10(dec). Same issue: want to send a 20(hex) it comes as a 32(dec) and should printed as 0
In short:
I send the 35, received as 53, but i need the 35 to reduce it by 20 and get the 15... how do i do that?
EDIT:
I am sorry for my yesterdays cofusing. WHat i need is to convert my received value to a BCD-number... nothing with hex ^^ should i delete this question now?
nothing is wrong.
for diny6:
30(hex) - 32(dec) = 30(hex) - 20(hex) = 10(hex) = 16(dec)
similarly for diny7.
integers by default are printed in decimal, thats why you get 16.
if you want to print the number in hex format do something like:
System.out.println(String.format("%x",diny6));
update:
i'm afraid you don't fully understand mathematical bases. hex and dec are just representations, an int variable isn't decimal or hex - it is just a number.
1. read the string representation of the number.
2. do whatever computations you need (and dont concern your self with the base during this stage).
3. print the result either as decimal or hex using format strings.
4. read up about the subject.
Was my own fault, misunderstood the meaning of what i wanted to do and ignored some hardware relevant requirements. Question totally wrong asekd.

Error on customers computer

I have a java client server program that works fine on a half a dozen computere but is causing a NegativeArraySizeException on site.
This is the code
location = message.indexOf("last");
location += 5;
end = message.indexOf('&', location);
int size = end - location; THIS IS THE ERROR LINE
char[] lastC = new char[size];
message.getChars(location, location+size, lastC, 0);
String firstS = new String(firstC);
String lastS = new String(lastC);
message is an xml message I am reading.
location is an integer that points the the location of a character in the message, the first name in this case.
size is the length of the persons name.
As far as I can tell size is being set as a negative number and I don't know why.
Does anyone know how to fix this or a better was of finding the length of the name ?
This is part of the server side.
As far as I can tell size is being set as a negative number and I don't know why.
If the first call to indexOf cannot locate "last" in the message, then location will be set to -1 and then incremented by 5 to give 4.
If the second call to indexOf cannot find a '&' then end will be set to -1, and size will be negative.
Obviously, the input XML is not in the form you expect.
All in all, that code is pretty dodgy. As a minimum you should check the results of both calls to indexOf and take appropriate error reporting / recovery steps if they are -1.
But the real fix is to not attempt to "parse" XML using crufty string bashing. Use an XML parser, preferably with validation against the relevant schema or DTD. If the XML parser rejects the input, report the error back at who / whatever gave you the broken XML.
Does the message contain last at all? If not, location would be negative, and you should stop processing right there. This error might go unnoticed because you add 5 to location after that, which makes it equal to at least 4 even if last is not in the string (thanks SJuan76).
Even if the message contains last, is it guaranteed that it is followed by at least one extra character? If not, adding 5 to location would point outside the string for sure.
Moreover, end may also be negative if there is no & in the string after location. You should handle that somehow (i.e. by setting end to the length of the message in that case).
Also, if message is a string, you can simply extract a substring of it using the substring method, no need for the getChars magic.
A better solution would probably be something like this (I'm assuming that message is something like an URL and you are looking for the part between last> and the next &, based on your comment for one of the other answers):
location = message.indexOf("last>");
if (location >= 0) {
String lastS;
location += 5;
end = message.indexOf('&', location);
if (end == -1) {
// Handle the case when there is no "&" after "last>" in the message
} else {
lastS = message.substring(location, end);
}
} else {
// Handle the case when there is no "last>" in the message
}
The trouble is that end is less than location. The issue is what message are you expecting and which one you are receiving; the rest of the logic works for certain messages. Check from where you get your message String.

What ways can you create a string with 2000 "spaces"

For various reasons I am trying to set a string to 2000 spaces. Currently I am using:
String s = String.format("%1$-2000s"," ");
This is great for Java 5, however, some of the developers in our department are using 1.4 and this does not work.
I was wondering, are any other ways of achieving the same result? I know I can do things like a for loop adding a space at a time, but I am looking for something simple like the format option.
For those that may be interested in why I need this, it is because we have an XML type on a dataobject that on insert into the DB is null. It then gets updated with the XML string, usually around 2000 characters in size. In Oracle pre-reserving this space can prevent row migration, therefore, increasing performance.
Thanks!
char[] spacesArray = new char[2000];
Arrays.fill(spacesArray, ' ');
String spaces = new String(spacesArray);
the simplest answer: (scroll to see all the codes)
String s = " "; // 2000 spaces
You can use lpad(' ',2000,' ') in the insert statement directly to tell Oracle to create the value you want.
In fact, you can set the field in question to have this as the default, which could prevent you from needing to change it in multiple places (if your code is explicitly sending null as the value for the field, that will override the default).
A StringBuffer and then add a space 2000 times in a loop, and toString() afterwards. I don't think there are any "simpler" ways to do it which doesn't end up doing this anyway under the covers.
If you do this a lot, it would make a good library function.
A random function I found in my personal library:
public static String whiteSpace2(int l) {
if (l==0) return "";
String half=whiteSpace2(l/2);
if ((l&1)!=0) {
return half+" "+half;
} else {
return half+half;
}
}
Not claiming it is the fastest possible way to generate whitespace, but it works :-)
StringUtils.repeat(" ", 2000) (from commons-lang)
However, I'm not sure whether such micro-optimizations should be made with the cost of code that would require a 5 line comment to explain why is this needed. If you do it - be sure to add an extensive comment, otherwise imagine the reaction of those reading your code.
If nothing else works:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 2000; ++i)
sb.append(" ");
String str = new String(sb);
See this other question.
Can I multiply strings in Java to repeat sequences?
Both Apache Commons StringUtils and Google Guava libraries have commands to multiply (repeat) strings.

Categories

Resources