Avatar billede dsj Nybegynder
04. august 2002 - 20:01 Der er 30 kommentarer og
1 løsning

konvertering af 32bit float

Baggrund:
Jeg er ved at udvikle et program, som henter oplysninger fra en CounterStrike-server. Blandt andet henter jeg oplysninger om spillerne: navn, antal frags OG HVOR LANG TID DE HAR SPILLET på serveren!

Hvad jeg ved:
Jeg får returneret et byte[], hvori oplysninger for alle spillerne er. Følgende er skrevet af Valve, som har lavet spillet (i C++):
for each active client
            (byte)        client number / index
            (string)    player name
            (int32)        client's frag total
            (float32)    client's total time in-game

Problemet:
Jeg ved hvilke 4 pladser i mit byte[] jeg skal finde den 32bit float som beskriver, HVOR LANG TID EN SPILLER HAR SPILLET på serveren.
Jeg ved bare ikke HVORDAN.

Kort:
En 32bit float som skal konverteres til en tidsperiode i formatet hh:mm:ss

Nogen ideer/løsninger?
Avatar billede stigc Nybegynder
04. august 2002 - 20:16 #1
Jeg kunne forstille mig du kunne gøre det sådan her, men er ikke absolut sikker;

float x;
x = byte[0]<<24 & byte[1]<<16 & byte[2]<<8 & byte[3];
Avatar billede =maddog= Nybegynder
04. august 2002 - 20:16 #2
en 32bit float bør ligge over fire byte.
det bør være sådan at hvis
playerInfo er dit byte array er
playerInfo[0] == clientNumber
playerInfo[1] til playerInfo[playerInfo.length-9] == player name
playerInfo[playerInfo.length-8] til playerInfo[playerInfo.length-5] == frag number
playerInfo[playerInfo.length-4] til playerInfo[playerInfo.length-1] == in game time

uden dog at have NOGEN som helst erfaring eller indsigt.
Avatar billede stigc Nybegynder
04. august 2002 - 20:16 #3
eller (fundet via google grupper)

float fValue;
BYTE ab[4] = {-98, 30, 60, 68};
memcpy(&fValue, ab, 4);
Avatar billede stigc Nybegynder
04. august 2002 - 20:17 #4
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&newwindow=1&threadm=fp7q7tk17jsqsk34tbtvhaf3jb46jkujp6%404ax.com&rnum=4&prev=/groups%3Fq%3D(float32)%2B%2B%2B%2Bclient%27s%2Btotal%2Btime%2Bin-game%26ie%3DISO-8859-1%26hl%3Den%26btnG%3DGoogle%2BSearch
Avatar billede =maddog= Nybegynder
04. august 2002 - 20:18 #5
mht. konvertering er stigc's kode vist skarp nok.
Avatar billede dsj Nybegynder
04. august 2002 - 21:55 #6
Det ser lovende ud. Hvordan gøres det i Java?
Avatar billede =maddog= Nybegynder
04. august 2002 - 21:59 #7
en float32 hedder double i Java. prøv først at se hvor langt dit array er med .length. Hvis det svarer til mit bud (ungefähr 20 bytes) kan jeg sagtens bikse noget sammen.
Avatar billede stigc Nybegynder
04. august 2002 - 22:14 #8
float x;
x = byte[0]<<24 & byte[1]<<16 & byte[2]<<8 & byte[3];

er også JAVA syntaks....
Avatar billede stigc Nybegynder
04. august 2002 - 22:14 #9
ik' helt, men;

double x;
x = byte[0]<<24 & byte[1]<<16 & byte[2]<<8 & byte[3];
Avatar billede =maddog= Nybegynder
04. august 2002 - 22:18 #10
stigc> det er mere henaf at lave en klasse
public class CSPlayer {
  private byte user_nr;
  private String user_name;
  private long total_frag;
  private double game_time;
 
  public CSPlayer(byte[] info) {
  // og saa videre
  }
  public String getName() {
    return this.user_name;
  }
  // og saa videre
}
gider bare ik' lave det hvis det kommer i et andet format.
Avatar billede stigc Nybegynder
04. august 2002 - 22:22 #11
ja, men det kan han vel selv bestemme, om han har lyst til. Spørgsmålet gik på konverteringen......
Avatar billede dsj Nybegynder
04. august 2002 - 22:24 #12
Jeg har læst at float er 32 bit i java og double er 64 bit:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html

Tager vi eksemplet fra ovenstående link fra stigc bliver x = 0.0 !!

byte[] ab = { -98, 30, 60, 68 }; // 0h 13m 52s = 832s
double x;
x = ab[0]<<24 & ab[1]<<16 & ab[2]<<8 & ab[3];

Hvad nu?
Avatar billede =maddog= Nybegynder
04. august 2002 - 22:26 #13
hvis en float er 32 bit bruger du bare det! jeg husker sikkert galt... det er sket et par gange før.
Avatar billede stigc Nybegynder
04. august 2002 - 22:27 #14
så må du vel bruge en float....
Avatar billede nico26 Nybegynder
04. august 2002 - 22:30 #15
bytes'ne skal or'es sammen - ikke and'es
Avatar billede stigc Nybegynder
04. august 2002 - 22:37 #16
Jamen, det er da også meget logisk. Jeg har byttet om på nogen operatore. Prøv:

       
    byte[] ab = { -98, 30, 60, 68 }; // 0h 13m 52s = 832s
    float x;
    x = ab[0]<<24  | ab[1]<<16 | ab[2]<<8 | ab[3];
Avatar billede dsj Nybegynder
04. august 2002 - 22:46 #17
I ekspemplet bliver resultatet -1.6421856E9
hvilket ikke helt ligner 832 :(
Avatar billede =maddog= Nybegynder
04. august 2002 - 23:29 #18
problemet ligger i at når vi laver left-shift er variablen stadig en byte og kan kun holde 8 bits.
Avatar billede dsj Nybegynder
04. august 2002 - 23:36 #19
hvad gør man så?
Avatar billede =maddog= Nybegynder
04. august 2002 - 23:44 #20
jeg er ikke i nærheden af at fatte hvad der går galt her. jeg troede problemet var det førnævnte men det er det vist ikke alligevel.
Avatar billede stigc Nybegynder
04. august 2002 - 23:58 #21
Jeg tror nu det er rigtig nok. Det er nok nærmere, hvordan man aflæser dette tidstempel, at problemet ligger. Jeg har dog ingen foreslag.
Avatar billede nico26 Nybegynder
04. august 2002 - 23:59 #22
hvorfor skal det gi 832?
Avatar billede =maddog= Nybegynder
05. august 2002 - 00:09 #23
der er altså lus i pelsen. hvis man vender det om
x = ab[3]<<24  | ab[2]<<16 | ab[1]<<8 | ab[0];
giver det -98, uanset de andre tre bytes (efter hvad jeg lige kunne fuske mig til).
Avatar billede dsj Nybegynder
05. august 2002 - 00:12 #24
Her har jeg udskrevet de 4 bytes, som beskriver tiden, med et sekunds mellemrum. Måske kan nogen se et system...

Første tidspunkt skulle være lig 00h 19m 00s

-94 , -120 , -114 , 68

-108 , -87 , -114 , 68

-108 , -55 , -114 , 68

-94 , -24 , -114 , 68

-108 , 9 , -113 , 68

-108 , 41 , -113 , 68

69 , 73 , -113 , 68

-108 , 105 , -113 , 68

-108 , -119 , -113 , 68

-15 , -88 , -113 , 68
Avatar billede =maddog= Nybegynder
05. august 2002 - 00:14 #25
is there a Mensa member in the house! anyone!
Avatar billede =maddog= Nybegynder
05. august 2002 - 00:15 #26
vent nu lige lidt. hvad er dit client number/index. vel ikke 68.
Avatar billede dsj Nybegynder
05. august 2002 - 00:21 #27
Nej client number er ikke 68, det tal ændre sig også, bare ret sjældent. Byte nr. 2 fra højre er ens 8 sekunder i træk, ændrer sig altså en gang 9. gang
Avatar billede =maddog= Nybegynder
05. august 2002 - 00:32 #28
en byte wrapper ved -128 (10000000) og 127 (01111111). Det er derfor relativt logisk at der går fra 127 til -128. Når byten står i nul 0 (00000000) tæller den næste også op, hvilket strengt taget også er logisk.
Mit problem er nu, at jeg ikke ved hvorledes de fire bytes i en float er ordnet.
Avatar billede dsj Nybegynder
06. august 2002 - 15:45 #29
Jeg har omsider fundet svaret:

int time = ((receive[j] & 255)) + ((receive[j+1] & 255) << 8) +
((receive[j+2] & 255) << 16) + ((receive[j+3] & 255) << 24);
Float fobj = new Float(time);
System.out.println(fobj.intBitsToFloat(time));

Men ellers tak for hjælpen :)
Avatar billede stigc Nybegynder
06. august 2002 - 18:24 #30
Tillykke, tillykke :)

(receive[j] & 255) er vist det sammme som receive[j], hvis der er tale om bytes...

Ligeledes med de tre andre.
Avatar billede nico26 Nybegynder
06. august 2002 - 18:35 #31
ja - det burde ikke have nogen effekt at and'e 255 på en byte
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester