string to float[]?

    Mar 09 2006 | 1:24 pm
    hi java heads, suppose you have floating point data in a string representation, terminated by a ";"
    String myData = "0.051 0.312 0.819 .... 0.123;" ;
    is there an easy way to convert this into a float array?
    myFloatArr[0] = 0.051; myFloatArr[1] = 0.312; myFloatArr[2] = 0.819; ... myFloatArr[x] = 0.123;
    thanks, volker.

    • Mar 09 2006 | 2:55 pm
      dunno how easy you're looking for, but this works:
      String myData = "0.051 -0.312 0.819 0.123;"; String[] myDataArr = myData.split(" +|;"); float[] myFloatArr = new float[myDataArr.length]; for (int i = 0; i < myDataArr.length; i++) { myFloatArr[i] = Float.valueof(myDataArr[i]).floatValue(); }
      you may want to tweak the regex used in .split() to make it a little more robust depending on the source of your myData strings..
      best regards, r.
    • Mar 09 2006 | 3:03 pm
      Hi Volker,
      This should work (using java.util.regex.Pattern is more efficient than String.split() for repeated calls, which I assume you want):
      String test = "0.001 0.002 0.003 0.004;";
      Pattern patt = Pattern.compile("[\s+,;]");
      String [] res = patt.split(test);
      float[] nums = new float[res.length];
      for(int i = 0; i { nums[i] = Float.parseFloat(res[i]); }
      Regex isn't exactly my strongest area, and this will blow up quite easily if there's unexpected input, so fails the 'liberal in what you receive' test, but if you're sure you'll be dealing with well-formed input it'll get the job done.
      -- Owen
    • Mar 09 2006 | 7:03 pm
      hey ritchie and owen, thanks for your suggestions. both your versions work. i had tried something similar - without success... but i found the mistake through your examples.
      actually the whole story is a little more complicated (or easier?) i'm receiving data via UDP from another app which is analysing images from a 3d camera. it's quite a lot of data (at 25 fps). so i'd really like to have that networking stuff as fast as possible...
      so i am receiving the data in a byte array and this byte stream represents floating point data (that's what the other app is sending) buffer[] myBytes = {50, 46, 55, 51, 55, 57, 54, 32, 45, 48, 46, 51, 57, 51, 53, 52, 54, 32, ... 59, 10}
      i would like to arrive at a float array to finally dump the data into a jitter matrix. float[] myFloats = {2.73796, -0.394, ... }
      String myDataString = new String(myBytes); this turns the whole thing into a string. so i could carry on with your suggestions. this works. (i have to watch out for the end of the string since floatValue() or parseFloat() doesn't like empty strings, but i managed to handle that)
      my other approach goes like this:
      StringBuffer sb = new StringBuffer(); String tempString = null; int i = 0; int index = 0;
      while(true) { if( myBytes[i]==32 ) { tempString = sb.toString(); floatArr[index] = Float.valueOf(tempString).floatValue(); index++; sb = new StringBuffer(); } else if( myBytes[i]==59 ) { tempString = sb.toString(); break; } else { sb.append((char)myBytes[i]); } i++; }
      is this a good idea? which approach would be better? seems like a common problem to me, so maybe there is something more straight forward? any suggestions welcome. thanks, volker.
    • Mar 09 2006 | 11:13 pm
      vb wrote: > my other approach goes like this:
      I couldn't tell you which would be more efficient, you'd have to test each and check it out. IMO the regex is easier to read for when you come back to the code, but perhaps slightly more awkward to tweak for unforeseen situations.
      If you really, really wanted to make it zippy the thing to do would be to produce a solution that avoids all the object creation associated with going from primitives to Strings and back to primitives (not that I'd really recommend this as a path to happiness ).
      Basically, as with your approach you can test for ' ' and ';' for delimiting, but you could also try and reconstruct the numbers from the character codes; search through a new token until you hit the decimal point, each digit leftwards of that can be looked up and added to the resulting float as a positive power of ten incremented by its distance from the floating point (starting at 0), and on the right negative powers of ten (starting at -1). That said, you may well get no discernible speed increase this way - I wouldn't consider trying it unless you discover one of the solutions already offered doesn't function (remember Knuth's rules of optimization :)
      What would be much better is if the sending app, if you're in any position to change its behaviour, just sent a stream of floats serialized as bytes, then reading them in would be dead quick.
      -- Owen
    • Mar 10 2006 | 10:47 am
      hi owen, thanks for your comments.
      > (remember Knuth's rules of optimization :) yeah, espescially if you don't really know what you are doing and your testing schemes are built on some voodoo magic, like mine... :) > > What would be much better is if the sending app, if you're in any > position to change its behaviour, just sent a stream of floats > serialized as bytes, then reading them in would be dead quick. while i'm not in the position to change this myself, i'm in contact with the person who is. but probably he'll yell at me, cause that would mean more work for him... still, definitely worth a try. thanks for the input, best, volker.