|
| 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 |
| | |
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 |
| | |
Larz (05-08-2002)
| Kommentar Fra : Larz |
Dato : 05-08-02 17:52 |
| | |
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.
| |
|
|