Skocz do zawartości

Rekomendowane odpowiedzi

Opublikowano

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.

Opublikowano

No to w takim razie ja nie widzę problemu, bo tu nigdzie nie jest napisane, żęby GM zapisywał odrazu 8 bajtowego zapisu.

 

file_bin_write_byte(fileid,byte) Zapisuje bajt danych do pliku o podanym id.

 

1 bajt, więc co za problem?

Opublikowano

@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

Opublikowano

No ale funkcja którą wkleiłem z tego artykułu mówi wyraźnie, że zapisuje tylko 1 bajt :/.

Teraz tak się zastanawiam, jak "rozerwać" liczbę na 8 bitowe częśći... Hmmm zerkne jeszcze do tego artu.

Opublikowano

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!

Opublikowano

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.

Opublikowano

To by nie miało żadnego logicznego sensu... Tutaj trzeba experta! Tymon!!!

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

Opublikowano

albo rozwiazania polubownego, narazie bede probowal to robic na wartosciach jedno bajtowych(przedzial 255 do -255)

pozniej moze jak ktos bardziej to rozumiejacy(tymon wlasnie np.) cos sie rozwiaze ;)

Opublikowano

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;

  • Administratorzy
Opublikowano

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

Opublikowano

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

  • Administratorzy
Opublikowano

$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

Opublikowano
. Myślałem, że znasz system szesnastkowy.

znam i nie przyszlo mi do glowy ze to o niego chodzi, nigdy ie operowalem w kodzie szesnastkowym w GM

Opublikowano

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.

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ę...