/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Convertering af 32bit float
Fra : Daniel Jacobsen


Dato : 05-08-02 08:18

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
(i Java)

Nogen ideer/løsninger?

Her har jeg udskrevet de 4 bytes, som beskriver tiden, udskrevet 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



 
 
Ulrik Magnusson (04-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 04-08-02 23:35



Daniel Jacobsen wrote:

> 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

Her er da et forslag:


class a
{
static int convert( int a, int b, int c, int d )
{
int i = 0;
i |= ~a;
i |= (~b << 8);
i |= (~c << 16);
i |= (~d << 24);
return ~i;
}

public static void main( String[] args )
{
System.out.println(convert(-94 , -120 , -114 , 68));
}
}

Skal jeg også prøve at forklare? - det må blive en anden dag..
Resultatet af ovenstående bliver 1150191778 - som ca.
svarer til 19 minutter i nanosekunder (NANOSEKUNDER!!??)

Ulrik Magnusson


Ulrik Magnusson (04-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 04-08-02 23:39

Ulrik Magnusson wrote:

> Skal jeg også prøve at forklare? - det må blive en anden dag..
> Resultatet af ovenstående bliver 1150191778 - som ca.
> svarer til 19 minutter i nanosekunder (NANOSEKUNDER!!??)

Det er selvfølgelig "kun" mikrosekunder (MIKROSEKUNDER!!??)

Ulrik Magnusson


Daniel Jacobsen (05-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 05-08-02 08:58

Jeg ved godt hvad du gør og har selv prøvet det. Et andet eksempel
1137915064 skulle være lig ca. 7 minutter - og det passer vist ikke helt :(
Hvis man switcher dem i denne rækkefølge er der lidt fornuft i tallenes
udvikling, som hvert sekund stiger med ca. en million (et sekund i
nanosekunder). men hvordan man skal kunne komme frem til 7 minutter ud fra
tallet 1137915064, er jeg ikke klar over.



Lars Dam (05-08-2002)
Kommentar
Fra : Lars Dam


Dato : 05-08-02 00:16

On Mon, 5 Aug 2002 00:57:45 -0700, "Daniel Jacobsen" <dj@g-a-f.dk>
wrote:

>Jeg ved godt hvad du gør og har selv prøvet det. Et andet eksempel
>1137915064 skulle være lig ca. 7 minutter - og det passer vist ikke helt :(
>Hvis man switcher dem i denne rækkefølge er der lidt fornuft i tallenes
>udvikling, som hvert sekund stiger med ca. en million (et sekund i
>nanosekunder). men hvordan man skal kunne komme frem til 7 minutter ud fra
>tallet 1137915064, er jeg ikke klar over.

Hvis tallet er i sin binære for et IEEE floating point værdi, så kan
man ikke caste/konvertere på denne måde. Brug enDataInputStream for at
få det indlæst korrekt, eller søg på google om hvordan dette format er
opbygget.

Eller bare den nemme løsning: brug Float.intBitsToFloat():

http://java.sun.com/j2se/1.4/docs/api/java/lang/Float.html#intBitsToFloat(int)

int værdien fåes ved den 'forkerte' metode som er vist tidligere.

vh. ld


Ulrik Magnusson (05-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 05-08-02 01:01



Lars Dam wrote:

> Eller bare den nemme løsning: brug Float.intBitsToFloat():
> http://java.sun.com/j2se/1.4/docs/api/java/lang/Float.html#intBitsToFloat(int)
> int værdien fåes ved den 'forkerte' metode som er vist tidligere.

Æv, så gættede jeg forkert (at det faktisk var en int der blev sendt..
- hvorfor sende et antal sekunder som float?)

Ulrik Magnusson


Thorbjoern Ravn Ande~ (05-08-2002)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 05-08-02 09:35

Ulrik Magnusson <ulrikm@yahoo.com> writes:

> Æv, så gættede jeg forkert (at det faktisk var en int der blev sendt..
> - hvorfor sende et antal sekunder som float?)

Så undgår man overløb ved meget store tider.
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn

Ulrik Magnusson (05-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 05-08-02 15:32



Thorbjoern Ravn Andersen wrote:

> Ulrik Magnusson <ulrikm@yahoo.com> writes:
> > Æv, så gættede jeg forkert (at det faktisk var en int der blev sendt..
> > - hvorfor sende et antal sekunder som float?)
> Så undgår man overløb ved meget store tider.

Gad vide om der er nogen, der spiller Counterstrike i mere
end 68 år? Er det mon ikke nærmere pga. den præcision
som man tror man får ved at bruge kommatal.

Ulrik Magnusson


Thorbjoern Ravn Ande~ (05-08-2002)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 05-08-02 23:33

Ulrik Magnusson <ulrikm@yahoo.com> writes:

> > > Æv, så gættede jeg forkert (at det faktisk var en int der blev sendt..
> > > - hvorfor sende et antal sekunder som float?)
> > Så undgår man overløb ved meget store tider.
>
> Gad vide om der er nogen, der spiller Counterstrike i mere
> end 68 år? Er det mon ikke nærmere pga. den præcision
> som man tror man får ved at bruge kommatal.

Jeg ved det ikke. Det var et bud.
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn

Daniel Jacobsen (05-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 05-08-02 11:30


ok, jeg har set lidt nærmere på IEEE Floating Point numbers.

Følgende kode:
byte[] ab = { 94, -120, -114, 68 }; // ca. 00:19:00 = 1140s
ByteArrayInputStream stream = new ByteArrayInputStream(ab);
DataInputStream data = new DataInputStream(stream);
data.readFloat();

Giver følgende resultat: 4.9199385E18

De andre metoder jeg har prøvet giver et negativt tal og passer ikke rigtig
på eksemplet her. Men hvordan får jeg noget brugbart ud af ovenstående
resultat??
Jeg skulle på en eller anden måde jo gerne ende op med et antal sekunder og
datoformatet hh:mm:ss.



Ulrik Magnusson (05-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 05-08-02 06:41


Daniel Jacobsen wrote:

> Følgende kode:
> byte[] ab = { 94, -120, -114, 68 }; // ca. 00:19:00 = 1140s
> ByteArrayInputStream stream = new ByteArrayInputStream(ab);
> DataInputStream data = new DataInputStream(stream);
> data.readFloat();
>
> Giver følgende resultat: 4.9199385E18

Problemet er sikkert at read() i ByteArrayInputStream returnerer
en værdi imellem 0 og 255 - jeg kan ikke lige finde en anden
brugelig klasse.

Ulrik Magnusson


Daniel Jacobsen (05-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 05-08-02 11:35

ææææhhhh. De test-tal jeg får har ikke rigtig noget mønster (når jeg gør som
ovenfor beskrevet) og skifter fra negativt til positivt og høje til lave
tal.

Mand det er langt ude det her (ryster lidt fortvivlet på hovedet).



Lars Dam (05-08-2002)
Kommentar
Fra : Lars Dam


Dato : 05-08-02 00:17

On Mon, 5 Aug 2002 00:57:45 -0700, "Daniel Jacobsen" <dj@g-a-f.dk>
wrote:

>Jeg ved godt hvad du gør og har selv prøvet det. Et andet eksempel
>1137915064 skulle være lig ca. 7 minutter - og det passer vist ikke helt :(
>Hvis man switcher dem i denne rækkefølge er der lidt fornuft i tallenes
>udvikling, som hvert sekund stiger med ca. en million (et sekund i
>nanosekunder). men hvordan man skal kunne komme frem til 7 minutter ud fra
>tallet 1137915064, er jeg ikke klar over.

Det er fordi tallet er i et IEEE Float format, Se andet indlæg for
detaljer.

vh.ld



Larz (05-08-2002)
Kommentar
Fra : Larz


Dato : 05-08-02 11:37

Lars Dam wrote:
> Det er fordi tallet er i et IEEE Float format, Se andet indlæg for
> detaljer.

Nærmere betegnet IEEE-754 single precision floating point :)
PHP kan heller ikke umiddelbart forstå det, så jeg lavede engang en
løsning til det:

   <http://ws.coder.dk/hl/hlMon.phps>

Se under players metoden.

--
-
Lars
http://coder.dk/sohofaq.php - Uofficiel WOL SOHO 77 FAQ
http://wshlman.moons.dk/ - Say goodbye to GameSpy
- A Free Half Life Manager!
To mail me remove your-pants.


Daniel Jacobsen (05-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 05-08-02 23:30


Larz det ligner det jeg har brug for. Jeg kan se du har gang i at læse sign,
eksponent osv., men har du mulighed for at oversætte det til Java for mig :)
Forstår ikke helt i detaljer hvad du gør.



Larz (05-08-2002)
Kommentar
Fra : Larz


Dato : 05-08-02 17:07

Daniel Jacobsen wrote:
> Larz det ligner det jeg har brug for. Jeg kan se du har gang i at læse sign,
> eksponent osv., men har du mulighed for at oversætte det til Java for mig :)
> Forstår ikke helt i detaljer hvad du gør.

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

Dér skriver de at javas float datatype netop er IEEE-754, så kan du ikke
cast'e den?

--
-
Lars
http://coder.dk/sohofaq.php - Uofficiel WOL SOHO 77 FAQ
http://wshlman.moons.dk/ - Say goodbye to GameSpy
- A Free Half Life Manager!
To mail me remove your-pants.


Larz (05-08-2002)
Kommentar
Fra : Larz


Dato : 05-08-02 17:52

Larz wrote:
> http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
>
> Dér skriver de at javas float datatype netop er IEEE-754, så kan du ikke
> cast'e den?

<http://java.sun.com/products/jdk/1.1/docs/api/java.lang.Float.html> kan
man ikke bruge intBitsToFloat metoden?
Jeg koder ikke selv java, og kender kun lidt til det, sååå ;)


--
-
Lars
http://coder.dk/sohofaq.php - Uofficiel WOL SOHO 77 FAQ
http://wshlman.moons.dk/ - Say goodbye to GameSpy
- A Free Half Life Manager!
To mail me remove your-pants.


Daniel Jacobsen (06-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 06-08-02 06:13

Hvis nu jeg caster med følgende kode:

float time = ((receive[j] & 255)) + ((receive[j+1] & 255) << 8) +
((receive[j+2] & 255) << 16) + ((receive[j+3] & 255) << 24);
System.out.println((time/1024)/16));

....stiger tallet på nogle servere med næsten præcis 1 for hvert sekund, mens
det på andre servere er præcist 2. Larz kunne du ikke forklare mig, hvordan
du gør i din kode, så jeg kan overføre det til java?

Mvh. Daniel J.



Ulrik Magnusson (05-08-2002)
Kommentar
Fra : Ulrik Magnusson


Dato : 05-08-02 21:53

Daniel Jacobsen wrote:

> Hvis nu jeg caster med følgende kode:
>
> float time = ((receive[j] & 255)) + ((receive[j+1] & 255) << 8) +
> ((receive[j+2] & 255) << 16) + ((receive[j+3] & 255) << 24);
> System.out.println((time/1024)/16));

Hvad var der galt med Float.intBitsToFloat() ? Ovenstående er jo det
samme som jeg fejlagtigt foreslog.

Ulrik Magnusson


Lars Dam (05-08-2002)
Kommentar
Fra : Lars Dam


Dato : 05-08-02 00:18

On Mon, 5 Aug 2002 00:57:45 -0700, "Daniel Jacobsen" <dj@g-a-f.dk>
wrote:

>Jeg ved godt hvad du gør og har selv prøvet det. Et andet eksempel
>1137915064 skulle være lig ca. 7 minutter - og det passer vist ikke helt :(
>Hvis man switcher dem i denne rækkefølge er der lidt fornuft i tallenes
>udvikling, som hvert sekund stiger med ca. en million (et sekund i
>nanosekunder). men hvordan man skal kunne komme frem til 7 minutter ud fra
>tallet 1137915064, er jeg ikke klar over.

Det er fordi tallet er i et IEEE Float format, Se andet indlæg for
detaljer.

vh.ld



Thorbjoern Ravn Ande~ (05-08-2002)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 05-08-02 09:34

"Daniel Jacobsen" <dj@g-a-f.dk> writes:

> En 32bit float som skal konverteres til en tidsperiode i formatet hh:mm:ss
> (i Java)

En float lagres normalt som noget i retning af 1.23456 * 10^123 (hvor
123... varieres - det kan også være med 2 som grundtal). Dvs her vil
jeg tro at en af byte'sene er en eksponent og de tre resterende det
der skal ganges på.

Kan du hitte ud af om det er en Windows type eller noget andet?
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn

Daniel Jacobsen (05-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 05-08-02 23:31

Jeg går stærkt ud fra at det er en Windows type, da spillet er et windows
spil.



Daniel Jacobsen (06-08-2002)
Kommentar
Fra : Daniel Jacobsen


Dato : 06-08-02 07:18

Jaaaaaa :D nu virker det. Der er kommet mange forslag og jeg har været lidt
forvirret over, hvad som var det rigtige. Følgende er det rigtige:

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));

Der skal selvfølgelig lyde en stor, stor tak til alle som har brugt tid på
at hjælpe mig. Jeg har kontaktet indtil flere fora samt eksperten.dk og har
først fået løsningen nu. Tag lige og klap jer selv på skulderen for mig :)

Mvh. Daniel J.



Søg
Reklame
Statistik
Spørgsmål : 177559
Tips : 31968
Nyheder : 719565
Indlæg : 6408937
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste