• Tidak ada hasil yang ditemukan

String-string Byte

Dalam dokumen Buku bhs pemrograman Q Equational 2018 (Halaman 166-169)

10 fungsi Built-In

11. Pustaka Standar

12.3 String-string Byte

Jenis yang berikut menunjukkan data biner tidak tersusun yang diterapkan sebagai vektor- vektor byte C. Struktur data ini digunakan oleh fungsi I/O yang low-level dan fungsi-fungsi clib lain yang membedah data biner.

public extern type ByteStr;

public isbytestr B; // check for byte strings

String-string byte seperti string karakter yang biasa, tetapi mereka tidak mempunyai suatu penyajian untuk dicetak, dan mereka boleh memasukkan di dalamnya nol byte-byte. (Ingat bahwa suatu byte kosong di suatu string karakter mengakhiri string.) Mereka dapat digunakan untuk menyandi data biner sembarang seperti vektor-vektor C dan struktur-struktur. Fungsi bytestr dapat digunakan untuk membangun string-string byte dari bilangan bulat, angka-angka floating point, nilai-nilai string atau daftar nilai-nilai byte yang tidak ditandai:

public extern bytestr X; // create a byte string

argument X menandakan data yang disandikan dan dapat juga daftar nilai-nilai byte (bilangan bulat yang tidak ditandai di dalam cakupan dari 0 sampai 255), atau satu obyek data yang atomic, yaitu., satu bilangan bulat, jumlah floating point atau konstan string. Kemudian kasus, argument itu dapat juga mempunyai bentuk (X,SIZE) yang menandakan ukuran byte yang diinginkan dari obyek; jika tidak suatu ukuran default yang layak dipilih. Jika ukuran yang ditetapkan berbeda dengan ukuran nyata dari X, hasil itu adalah kosong yang diisi atau dipotong secara setimpal. Nilai-nilai bilangan bulat disandikan di dalam pesanan byte host, dengan anggota GMP paling sedikit penting terlebih dulu; integer negatif diwakili dalam komplemen 2. Nilai-nilai floating point disandikan dengan ketepatan ganda secara langsung atau jika perhitungan byte adalah cukup (yaitu., sedikitnya 8 di kebanyakan sistem), dan menggunakan ketepatan tunggal cara lainnya. String-string secara langsung disandikan di dalam pengkodean sistem, tetapi anda dapat juga menetapkan pengkodean target yang diinginkan seperti

(X,CODESET) (atau (X,CODESET,SIZE) jika anda juga perlu untuk menetapkan suatu ukuran byte), di mana CODESET adalah suatu string menandakan pengkodean target.

Seperti string karakter yang biasa, string-string byte dapat digabungkan, ukuran yang dapat diukur, diindekkan, lexicographically dibandingkan dan diiris. Lebih dari itu, suatu string byte dapat dikonversi kembali ke sebuah (multiprecision) bilangan bulat, jumlah floating point, nilai string, atau daftar nilai-nilai byte. (Ketika mengubah kembali ke string, anda dapat menetapkan pengkodean sumber seperti di bstr (B,CODESET), jika tidak pengkodean sistem diasumsikan.) Untuk maksud ini operasi yang berikut disediakan.

public extern bcat Bs; // concatenate list of byte strings public extern bsize B; // byte size of B

public extern byte I B; // Ith byte of B

public extern bsub B I J; // slice of B (bytes I..J) public extern bcmp M1 M2; // compare M1 and M2

public extern bint B; // convert to unsigned integer public extern bfloat B; // convert to floating point number public extern bstr B; // convert to string

public bytes B; // convert to list public ::list B; // ditto

Anda dapat menggunakan fungsi byte untuk mengkonversi suatu string byte menjadi daftar nilai-nilai byte; fungsi daftar dimuati berlebihan untuk menyediakan kemampuan yang sama. Fungsi-fungsi ini digambarkan sebagai berikut:

bytes B:ByteStr = map (B!) [0..#B-1]; list B:ByteStr = bytes B;

Untuk kenyamanan, operator string yang umum dan sub fungsi dimuati berlebihan untuk bekerja di string-string byte juga. Dengan demikian #B mengembalikan ukuran dari B (banyaknya byte-byte yang berisi) dan B!I byte Ith dari B. B1++B2 menggabungkan B1 dan B2, sub B I J mengembalikan irisan dari byte I ke J, dan operator relasional `=', `<', `>', dll. dapat digunakan untuk membandingkan string-string byte lexicographically. Operasi ini semuanya diterapkan dalam kaitannya dengan penggunakan istilah daftar fungsi-fungsi di atas. Contoh-contoh

menyandikan satu bilangan bulat sebagai suatu string byte, memperhatikan byte-byte nya yang individu, dan mengkonversi string byte kembali ke satu bilangan bulat:

==> hex

==> def B = bytestr 0x01020304; bytes B; bint B [0x4,0x3,0x2,0x1]

(Catatan bahwa hasil ini diperoleh di suatu sistem little-endian, karenanya 0x04 byte penting paling sedikit yang datang pertama di dalam daftar byte.)

Integer negatif secara benar disandikan dalam komplemen 2:

==> def B = bytestr (-2); bytes B; bint B [0xfe,0xff,0xff,0xff]

0xfffffffe

untuk bekerja bersama representasi biner ini, anda harus sadar akan cara GMP menunjukkan multiprecision bilangan bulat. Secara khusus, catatan bahwa ukuran default dari suatu bilangan bulat adalah selalu suatu perkalian (sedikitnya satu) dari ukuran anggota GMP yang biasanya 4 atau 8 byte yang tergantung pada sistem host defaultnya jenis bilangan bulat yang panjang. Ukuran anggota yang nyata dapat ditentukan sebagai berikut:

==> #bytes (bytestr 0)

Untuk memperoleh bilangan bulat dari ukuran-ukuran yang sembarang, satu argument eksplisit SIZE bisa digunakan. Sebagai contoh, di sini bagaimana kita menyandi bilangan bulat yang kecil (1 atau 2 byte):

==> bytes (bytestr (0x01,1)); bytes (bytestr (0x0102,2)) [0x1]

[0x2,0x1]

Ukuran-ukuran byte dari sistem host dari berbagai tipe atomic C yang dapat ditentukan dengan nilai simbolik yang dinyatakan pada awal clib.q, seperti SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_LONG, SIZEOF_FLOAT dan SIZEOF_DOUBLE.

fakta lain menyebutkan bahwa bahkan di sistem big-endian, bilangan bulat selalu disandikan dengan "anggota penting paling sedikit" terlebih dulu. Maka, sebagai contoh, selama ukurannya adalah 4, seperti di contoh-contoh tersebut, bilangan bulat 2-limb 0x0102030405060708 terdiri dari byte 0x8 0x7 0x6 0x5 0x4 0x3 0x2 0x1 di suatu sistem little-endian, di pesanan tersebut, sedangkan byte memesan di suatu sistem big-endian adalah 0x5 0x6 0x7 0x8 0x1 0x2 0x3 0x4. Di sini bagaimana kita dapat dengan cepat memeriksa pesanan byte dari sistem host:

==> hd (bytes (bytestr 1))

Ekspresi ini kembalikan 1 di suatu sistem dan kosong little-endian cara lainnya.

Selama satu bilangan bulat tidak melebihi ukuran kata mesin itu (yang biasanya memenuhi ukurannya), kita hanya dapat mengkonversi antara big-endian dan penyajian little-endian dengan pembalikan daftar byte:

==> bytestr (reverse (bytes B))

Nilai-nilai floating point dapat disandikan juga di dalam ketepatan ganda atau tunggal, tergantung pada argument SIZE. Ukuran default adalah ketepatan ganda (biasanya 8 byte).

==> bfloat (bytestr (1/3)); bfloat (bytestr (1/3,SIZEOF_FLOAT)) 0.333333333333333

0.333333343267441

Ukuran default dari pengkodean suatu string karakter adalah ukuran byte dari string di dalam pengkodean target (pengkodean sistem secara langsung). Jika satu ukuran yang tegas diberikan, string itu adalah kosong yang diisi atau yang dipotong jika perlu. Contoh yang berikut akan bekerja dengan setiap pengkodean sistem berdasar pada 7 bit ASCII (seperti Latin1, UTF-8 atau ASCII diri sendiri):

==> dec

==> def S1 = bytestr "ABC", S2 = bytestr ("ABC",2), S3 = bytestr ("ABC",5) ==> bytes S1; bytes S2; bytes S3

[65,66,67] [65,66] [65,66,67,0,0] ==> bstr S1; bstr S2; bstr S3 "ABC" "AB" "ABC"

Oleh unsur-unsur kombinasi seperti yang di atas, dan termasuk yang informasi "tagging" yang sesuai, struktur data lebih rumit dapat diwakili seperti data biner dengan baik. Untuk tujuan ini, string-string byte etiket-etiket dan elemen data itu dapat digabungkan dengan bcat atau operator `++'. Ini bermanfaat, khususnya, untuk penyimpanan yang ringkas dari object di dalam file-file. Lebih dari itu, beberapa fungsi sistem melibatkan data biner yang mungkin menunjukkan struktur-struktur C dan/atau vektor-vektor. Data seperti itu dapat dirakit dari bagian utama hanya oleh penggabung mereka. Sebagai contoh, menganggap struct C yang berikut:

struct { char foo[108]; short bar; int baz; };

Suatu nilai dari jenis ini, berkata {"Salam, dunia.", 4711, 123456}, kemudian bisa disandikan sebagai berikut:

==> bytestr ("Hello, world.",108) ++ bytestr (4711,SIZEOF_SHORT) ++ \ bytestr (123456,SIZEOF_INT)

Dengan cara yang sama, daftar bilangan bulat dapat dikonversi menjadi suatu vektor C yang sesuai sebagai berikut:

==> bcat (map bytestr [1..100])

Ketika menyandi seperti struktur-struktur C, anda harus pula menganggap penjajaran keluaran. Sebagai contoh, kebanyakan compiler-compiler C akan membariskan data yang bukan byte pada alamat-alamat lengkap.

Dalam dokumen Buku bhs pemrograman Q Equational 2018 (Halaman 166-169)