Cześć,
zna ktoś może metodę jak zamienić standardowego doubla na unsigned doubla :] ?
Nie mogę nigdzie znaleźć jak to trzeba zrobić, był bym bardzo wdzięczny za pomoc.
W Javie nie ma typów bez znakowych.
karol86 napisał(a)
W Javie nie ma typów bez znakowych.
to że nie ma to wiem :) bo bym sobie już dawno zrzutował :D ale to nie oznacza że nie możesz sobie ich reprezentować np. masz signed byte, żeby był unsigned robisz:
byte b;
int unsigned = b &0xFF
i teraz problem w tym, że nie wiem jak przerobić tak doubla :)
nawet znalazłem na stronce 4programmers taki artykuł:
"Emulacja liczb unsigned" w javie :)
Emulacja liczb unsigned
Tylko jest mały problem
"Strona w budowie
Ktoś pracuje nad tą stroną, jej zawartość może się wkrótce zmienić. Prosimy o cierpliwość!"
@schizo, strona jest w budowie bo to trzeba napisać. Problem niedawno się już pojawił i dziś wieczorkiem powinien pojawić się wstęp i namiar na svna z projektem.
Popatrz na bibliotekę Colt może tam coś będzie bo chłopaki z Cernu pewno potrzebują bezznakowego doubla.
Luknąłem na tą bibliotekę Colt i jest owszem "ByteConverter" ale niestety pozwala czytać na unsigned:
byte
int
short
ale doubla niestety nie :) po prostu muszę z pliku flasha (swf) zczytać sobie doubla jest on w postaci hex:
90 D4 5E 40 27 A1 F4 85
i jest to typ unsigned 64 bity Little endian.
Jest to wartość: 123.321
jednak kiedy czytam to sobie np z byteBuffera mam:
-5.682413746185032E-280
:/ bo jest on ze znakiem :./ i nie wiem jak sobie z tym poradzić...
o heh udało mi się :] przerobić signed double na unsigned double ale tylko przypadkiem :D bo w pętli ustawiłem za mało iteracji :P i ten błąd poskutkował otrzymaniem dobrego wyniku heh normalnie jestem z siebie dumny :P zaraz wkleję jak to wygląda :D
Kod trochę nieładny i nadmiarowy ale nie chce mi się go optymalizować, zainteresowany na pewno sobie to zoptymalizuje :P
Więc wygląda to tak:
ByteBuffer bbuf = ByteBuffer.allocate(10000); // tutaj trzymam dane
byte [] bn = new byte[8]; //to jest tablica do której przekopiuje sobie 8 bajtów na doubla
bbuf.get(bn,0,8); //kopiuję 8 bajtów z ByteBuffera do tablicy
unsignedDoubleToDouble(bn); // metodka
public static final long unsignedDoubleToDouble(byte[] b)
{
byte[] bb = new byte[8];
int t=3;
for (int nn = 0; nn<4;nn++){ //zamieniam miejscami bajty aby mieć Little endian
bb[nn] =b[t];
t--;
}
t=7;
for (int nn = 4; nn<=7;nn++){ //zamieniam miejscami bajty aby mieć Little endian
bb[nn] =b[t];
t--;
}
ByteBuffer b1 = ByteBuffer.allocate(18); // alokuje pamiec na moje 8 bajtow
for (int nn = 0; nn<7;nn++){ // wrzucam do ByteBuffera tylko!!! 7 bajtow :)
b1.put(bb[nn]);
}
long l = 0;
l |= bb[0] & 0xFF;
l <<= 8;
l |= bb[1] & 0xFF;
l <<= 8;
l |= bb[2] & 0xFF;
l <<= 8;
l |= bb[3] & 0xFF;
l <<= 8;
l |= bb[4] & 0xFF;
l <<= 8;
l |= bb[5] & 0xFF;
l <<= 8;
l |= bb[6] & 0xFF;
l <<= 8;
l |= bb[7] & 0xFF;
System.out.println("wynik long " + Double.longBitsToDouble(l));
return l;
}
aha ogólnie to na wikipedi piszą ze ostatni bit albo pierwszy (little endian) jest bitem znaku wiec chyba nie powinienem wywalać calego bajtu tylko 1 bit ? i być może to nie działa na większych liczbach :P
sorka głupoty tam napisałem bo już sam tak namieszałem ze nie wiem co napisałem :D ogólnie to trzeba zrobić tak:
ByteBuffer bbuf = ByteBuffer.allocate(10000); // tutaj trzymam dane
byte [] bn = new byte[8]; //to jest tablica do której przekopiuje sobie 8 bajtów na doubla
bbuf.get(bn,0,8); //kopiuję 8 bajtów z ByteBuffera do tablicy
unsignedDoubleToDouble(bn); // metodka
public static final long unsignedDoubleToDouble(byte[] b)
{
byte[] bb = new byte[8];
int t=3;
for (int nn = 0; nn<4;nn++){ //zamieniamy miejscami żeby był little endian
bb[nn] =b[t];
t--;
}
t=7;
for (int nn = 4; nn<=7;nn++){ //zamieniamy miejscami żeby był little endian
bb[nn] =b[t];
t--;
} //jeżeli chcesz big endian to wywal petle
long l = 0;
l |= bb[0] & 0xFF; //iloczyn logiczny and z 11111111
l <<= 8;
l |= bb[1] & 0xFF;
l <<= 8;
l |= bb[2] & 0xFF;
l <<= 8;
l |= bb[3] & 0xFF;
l <<= 8;
l |= bb[4] & 0xFF;
l <<= 8;
l |= bb[5] & 0xFF;
l <<= 8;
l |= bb[6] & 0xFF;
l <<= 8;
l |= bb[7] & 0xFF;
System.out.println("wynik long " + Double.longBitsToDouble(l));
return l;
}
Sorka jeszcze raz !!!
i jeszcze short int byte:
public static int unsignedByteToInt(byte b) {
return (int) b & 0xFF;
}
public static int unsignedShortToInt(short b) {
return (int) b & 0xFFFF;
}
public static int unsignedIntToInt(int b) {
return (int) b & 0xFFFFFFFF;
}
:) tak dla zainteresowanych
@schizo złączyłem posty. Zresztą zarejestruj się i wtedy będziesz mógł poprawiać swoje posty, a nie spamować mi tu forum (wyszedł ze mnie moderator oj... [diabel] ).
Co ważne to fajnie by było, jakbyś do tamtego artykułu dorzucił kod wraz z porządnym komentarzem i krótkim wstępem teoretycznym.
sorka ale tak na szybkiego chciałem złapać informacje :] i nie chciało mi się rejestrować :P spoko mogłeś w sumie usunąć ten pierwszy kod bo był bez sensu troszkę :P
teoretycznie to jest tak, że jak sie chce zrobić z signed byte -> unsigned byte to robimy:
byte b;
b & 0xFF ;
:) no a inne typy to po prostu np Integer 4 bajty czyli do każdego bajtu trzeba zrobić iloczyn z 0xFF
short 2 bajty
Double 8 bajtów
nie umiem tego wytłumaczyć "od podstaw"...musiał bym sobie wziąć książeczkę, poczytać i przypomnieć... i chyba mi sie nie chce... dla chętnych rządnych wiedzy książka:"informatyka w ogólnym zarysie" J. Glenn Brookshear rozdział 1.6 Reprezentacja liczb całkowitych