14. maj 2003 - 20:30
Der er
13 kommentarer og 2 løsninger
byte til float og int
Jeg har 2 bytearrays der er 4 stort, dvs. 32 bit pr. stk. Indholdet ønsker jeg at konvertere til en int og en float. private int frags; private float time; public void setFrags(byte frags[]) { this.frags = ??? } public void setTime(byte time[]) { this.time = ??? } Eksempler på indhold af array: Frags: 29 0 0 0 time: -66 -33 -84 71 Frags: 18 0 0 0 time: -1 127 -40 68 Frags: 10 0 0 0 time: -66 -33 -84 71 Frags: 23 0 0 0 time: -65 76 -14 68 Hvordan gør jeg nemmest ?
Annonceindlæg fra Barco
Du mener: hvordan laver man en union i Java ? :-)
du sidder vel ikke tilfældigvis og henter informationer fra en CS Server :) ?
For int kan du bare bruge << og |, men det er lidt bøvlet for float. Jeg tror du skal skrive/læse til et byte array som stream.
arne: Jeg henter nogle bytes fra en server og disse skal jeg have konverteret til noget brugbart. Jeg har aldrig rigtig forstået unions.. så jeg har ikke et svar på dit spørgsmål :-) dsj: Tjaaa, det er en tfc server - men det er samme info der hentes :-)
Loop de enkelte bytes igennem og læg dem sammen ganget med de respektive faktorer: int resultat; for (int i=0; i<4; i++) { resultat = resultat + ((long) Math.pow(2, i*8)) * frags[i]; } frit fra hovedet, der tages forbehold for trykfejl og prisændringer /Elv
Eksempel: import java.io.*; public class Union { public static void main(String[] args) { byte[] b = { 29, 0, 0, 0, -66, -33, -84, 71 }; try { ByteArrayInputStream ba = new ByteArrayInputStream(b); DataInputStream dis = new DataInputStream(ba); System.out.println(dis.readInt()); System.out.println(dis.readFloat()); } catch (IOException e) { e.printStackTrace(); } } }
Hmmm. Tilsyneladende er DataInputStream big endian !? Så: import java.io.*; public class Union { public static void main(String[] args) { byte[] b = { 0, 0, 0, 29, 71, -84, -33, -66 }; try { ByteArrayInputStream ba = new ByteArrayInputStream(b); DataInputStream dis = new DataInputStream(ba); System.out.println(dis.readInt()); System.out.println(dis.readFloat()); } catch (IOException e) { e.printStackTrace(); } } }
Denne metode henter tiden: public void setTime(byte time[]) { int j = 0; int time = (time[j++] & 255) + ((time[j++] & 255) << 8) + ((time[j++] & 255) << 16) + ((time[j++] & 255) << 24); time = StrictMath.round(fobj.intBitsToFloat(time)); String hour = StrictMath.round(time/3600)+""; String min = StrictMath.round((time%3600)/60)+""; String sec = StrictMath.round(time%60)+""; if (min.length() == 1) min = "0"+min; if (sec.length() == 1) sec = "0"+sec; this.time = hour+":"+min+":"+sec; }
Og denne metode henter antallet af frags: public void setFrags(byte frags[]) { int j = 0; this.frags = (frags[j++] & 255)+((frags[j++] & 255) << 8)+((frags[j++] & 255) << 16)+((frags[j++] & 255) << 24); }
Jeg har lavet et server-tool til half-life og alle mods. Ovenfor viste kode er snuppet derfra og tilpasset til dine to metoder.
Der er 4 pladser (bytes) der skal læses i henholdsvis time[] og frags[] og metoderne forudsætter begge, at data er placeret på index 0 - 3.
Søren - kender du ikke union - jeg troede du gjorde meget i C også ? I C er dette her pære nemt: union myunion { char b[4]; int i; float f; }; union myunion data; de 3 typer ligger så oven i hinanden og man kan bare læse ind i data.b og bruge data.i og data.f !
Umiddelbart tror jeg at DataInputrStream og DataOutputStream giver "pæneste" kode. Men der skal naturligvis være helt styr på om du får data i little endian eller big endian (eller net order).
Ok, jeg kigger på det - men nok ikke idag (jeg skal lige have lave det snavs jeg har lavet til noget objekt orienteret kode). Arne: Jeg kender godt union, men jeg har aldrig brugt den. Den vil vel heller ikke kunne bruge i dette tilfælde - endian er vel forkert ?
Også med union ville man skulle skifte endianess. Men det er jo ikke så svært at swappe 0 og 3 samt 1 og 2.
Kurser inden for grundlæggende programmering