Skocz do zawartości

zapisywanie liczb do pliku w postaci 2-bajtowej


TheMarcQ

Rekomendowane odpowiedzi

Poczytaj o obsłudze plików binarnych (na końcu):

https://gmclan.org/index.php?wiki=article&zm=56

 

I jeszcze o operatorach bitowych:

https://gmclan.org/index.php?czytajart=72

 

I po prostu w jednym bajcie zapisuj 8 bitów liczby, a w drugim kolejne jej 8 bitów.

Kolejny bajt to pierwsze 8 bitów kolejnej liczy i następny bajt to kolejne 8 bitów tej liczby.

 

W ten sposób z każdej liczby zapisujesz tylko 16 bitów (2 bajty) zamiast wszystkich 64.

Odnośnik do komentarza
Udostępnij na innych stronach

@pablo: GM zapisuje liczby w formacie long, czyli 8-bajtowe(64 bity) dzieki czemu moze zapisac bardzo duze liczby z zakresu <-9 223 372 036 854 775 808 - 9 223 372 036 854 775 807>, mi potrzebne sa liczby 2-bajtowe(16 bitow) z zakresu <-32 768 - 32 767> do edytora map do gry w javie

Odnośnik do komentarza
Udostępnij na innych stronach

juy mam roywiayanie:

>> - przesunięcie w prawo

 

Działanie niemal identyczne jak w przypadku poprzedniego operatora. Tutaj jednak wszystkie bity przesuwane są w prawo, a z lewej strony pozostają nam zera.

45          0101101
45 >> 3     0000101

wystarczy jako drogi zapisywany bajt podac zmienna z przesunietymi o 8 pozycji bitami

E:* juz mam rozwiazanie, ctrl+shift to zuo!

Odnośnik do komentarza
Udostępnij na innych stronach

No właśnie to jest marne rozwiązanie bo taka liczba z GMa o ile rozumiem wygląda sobie tak:

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100 0000 0000 0000

Czyli 64 bity

Teraz jak sobie przesuniesz to o 8 miejsc w prawo to będzie

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100 0000

a GM i tak zapisze cały ten zaj****cie długi ciąg do pliku bo nigdzie nie jest powiedziane, że pierwsze zera pominie.

 

Nie mam pojęcia jak to zrobić :D

JAK wyciągnąć sobie to pierwsze 1100 0000 a później 0000 0000 i pozniej kolejne 0000 0000 z tej liczby :D.

Odnośnik do komentarza
Udostępnij na innych stronach

Więc, sam się bawiłem plikami binarnymi w GMie:

 

Funkcja 'file_bin_write_byte' zapisuje tylko(!) 1 bajt(8 pierwszych bitów).

 

Dobrze by jeszcze było, żeby ktoś wyjaśnił co się podaje jako drugi argument w tej funkcji z zapisem bajta, bo przecież jak podasz sobie liczbę 103456 to to jest na więcej niż 1 bajcie :D
W drugim argumencie podaje się wartość dla 1 bajta (0-255...), jeśli więc podasz wartość wyższą niż pozwala na to 1 bajt, zapisane pozostaje tylko pierwszych 8 bitów(!)

 

Zatem, aby zapisać 2 bajty do pliku, trzeba posłużyć się operatorami bitowymi:

bajt1 = (wartosc >> 0) & $FF;
bajt2 = (wartosc >> 8) & $FF;

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

O to chodzi?

 

GML
f = file_bin_open('test.txt',1);

liczba = 29876;

file_bin_write_byte(f,liczba & $FF);

file_bin_write_byte(f,(liczba >> 8) & $FF);

file_bin_close(f);

 

f = file_bin_open('test.txt',0);

liczba = 0;

liczba = file_bin_read_byte(f);

liczba = liczba | (file_bin_read_byte(f) << 8 );

file_bin_close(f);

 

show_message(string(liczba));

 

game_end();

Odnośnik do komentarza
Udostępnij na innych stronach

To oznacza, że pobierze tylko 8 ostatnich bitów.

 

l1 = 65467564

l2 = (l1 >> 8) & $FF (= 244)

11111001101111010010101100 l1

 

00000000111110011011110100 l1 >> 8

00000000000000000011111111 & $FF

------------------------

00000000000000000011110100 l2

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

$FF to jest to samo co 0xFF, czyli zapis szesnastkowy liczby 255 - bo GM takowy obsługuje, chociaż w dokumentacji jest to w mało widocznym miejscu wspomniane. A & $FF to jest operacja and binarnie.

 

Zgodnie z zasadami algebry Boole'a, aby w liczbie wyzerować jakieś pozycje, należy wykonać operację AND, wstawiając zera tam gdzie zerujemy, a jedynki tam gdzie nie chcemy nic zmieniać. Ze względu na to jak działa and, tam gdzie jest zero w liczbie czy w masce, zawsze pozostanie zero, więc jeśli zero przejdzie przez maskę jedynki nadal pozostanie zerem, a jeśli jedynka przez maskę zera, to stanie się zerem. W związku z tym jedynki przejdą tylko tam gdzie liczba i maska mają jedynkę, a zera nadal pozostaną zerami mimo jedynkowej maski.

 

liczba  10101010
maska  &00111100
wynik  =00101000

 

Z kolei aby z jakiejś liczby przepisać jedynki do drugiej, wystarczy zrobić operację OR, czyli | - tam gdzie pojawi się jedynka której wcześniej nie było zostanie ona przepisana.

 

liczba  10101010
maska  |00111100
wynik  =10111110

 

Edit: pewnie to wiecie, ale tłumaczenie to dla tych co nie wiedzą :P

Odnośnik do komentarza
Udostępnij na innych stronach

System szesnastkowy przydaje się, gdy chce się zapisać kod jakiegoś koloru - zamiast jakichś trudnych do zapamiętania liczb masz ładnie zapisane w kodzie szesnastkowym.

I tak: niebieski to $FF0000

zielony - $00FF00

czerwony - $0000FF

I jest mnóstwo kombinacji.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...