Saya ingin skema untuk mewakili angka integer yang dimulai dengan 0, tanpa batas (dengan asumsi akses ke penyimpanan linier tak terbatas).
Berikut skema yang dapat mewakili angka dari 0 hingga 255:
Gunakan byte pertama dari penyimpanan (alamat 0) untuk menyimpan integer.
Sekarang, misalkan saya ingin mewakili angka yang lebih besar dari 255. Tentu saja, saya bisa menggunakan lebih dari 1 byte untuk mewakili integer, tetapi selama itu adalah angka tetap, pada akhirnya akan ada integer yang begitu besar sehingga tidak dapat diwakili oleh skema asli.
Berikut skema lain yang harus dapat melakukan tugas, tetapi mungkin jauh dari efisien.
Cukup gunakan semacam byte "end of number" yang unik, dan gunakan semua byte sebelumnya untuk mewakili nomor tersebut. Jelas, byte "akhir angka" ini tidak dapat digunakan di mana saja dalam representasi angka, tetapi ini dapat dicapai dengan menggunakan sistem penomoran basis-255 (bukan basis-256).
Namun, itu lambat dan mungkin tidak efisien. Saya ingin memiliki yang lebih baik yang berkinerja lebih baik dengan nilai dan skala rendah dengan baik.
Pada dasarnya, ini adalah sistem UUID. Saya ingin melihat apakah mungkin untuk membuat sistem UUID yang berkinerja cepat yang dapat secara teoritis skala untuk digunakan selama bertahun-tahun, ribuan tahun, jutaan tahun, tanpa harus dirancang ulang.
Jawaban:
Suatu pendekatan yang saya gunakan: hitung jumlah bit terdepan 1, katakanlah
n
. Ukuran angka kemudian 2 ^ n byte (termasuk 1 bit terkemuka). Ambil bit setelah 0 bit pertama sebagai integer, dan tambahkan nilai maksimum (plus satu) yang dapat diwakili oleh angka menggunakan pengkodean ini dalam 2 ^ (n-1) byte.Jadi,
Skema ini memungkinkan nilai non-negatif diwakili dengan tepat dalam satu cara.
(Setara, digunakan jumlah 0 bit terkemuka.)
sumber
Ada banyak teori yang didasarkan pada apa yang Anda coba lakukan. Lihatlah halaman wiki tentang kode universal - ada daftar lengkap metode pengkodean bilangan bulat (beberapa di antaranya sebenarnya digunakan dalam praktik).
Atau Anda bisa menggunakan 8 byte pertama untuk menyimpan panjang angka dalam beberapa unit (kemungkinan besar byte) dan kemudian meletakkan byte data. Akan sangat mudah diimplementasikan, tetapi agak tidak efisien untuk jumlah kecil. Dan Anda akan dapat membuat kode integer cukup lama untuk mengisi semua drive data yang tersedia untuk umat manusia :)
sumber
Bagaimana kalau jumlah angka 1 di depan ditambah angka 0 pertama menjadi ukuran (sizeSize) dari ukuran angka (numSize) dalam bit. NumSize adalah angka biner yang memberikan ukuran representasi angka dalam byte termasuk bit ukuran. Bit yang tersisa adalah angka (num) dalam biner. Untuk skema bilangan bulat positif, berikut adalah beberapa contoh nomor contoh:
sumber
Bagaimana dengan itu: Satu byte untuk panjang, kemudian n byte untuk nomor (byte paling signifikan pertama). Ulangi panjang + angka selama panjang sebelumnya 255.
Ini memungkinkan untuk jumlah besar yang sewenang-wenang, tetapi masih mudah ditangani dan tidak menghabiskan terlalu banyak memori.
sumber
Mengapa tidak menggunakan 7 bit saja dari setiap byte, dan menggunakan bit ke-8 untuk menunjukkan apakah ada byte lain yang harus diikuti? Jadi 1-127 akan berada dalam satu byte, 128 akan diwakili oleh 0x80 0x01, dll.
sumber
Sistem UUID didasarkan pada daya komputasi yang terbatas (tetapi besar) di alam semesta yang terbatas (tetapi besar). Jumlah UUID besar bahkan jika dibandingkan dengan hal-hal besar yang tidak masuk akal seperti jumlah partikel di alam semesta. Jumlah UUID, dengan jumlah bit tetap apa pun, kecil, dibandingkan dengan tak terbatas.
Masalah dengan menggunakan 0xFFFF untuk mewakili flag angka Anda adalah membuat pengodean nomor Anda menjadi kurang efisien ketika angka besar. Namun, tampaknya skema UUID Anda memperburuk masalah ini. Alih-alih satu dari 256 byte dilewati, Anda sekarang memiliki seluruh ruang UUID terbuang. Efisiensi perhitungan / pengenalan (alih-alih ruang) banyak bergantung pada komputer teoretis Anda (yang, saya asumsikan Anda miliki jika Anda berbicara tentang infinity). Untuk TM dengan selotip dan pengontrol keadaan terbatas, skema UUID apa pun tidak mungkin untuk menskalakan secara efisien (pada dasarnya, lemma pemompaan mengacaukan Anda dari bergerak melampaui penanda ujung dengan panjang bit tetap secara efisien). Jika Anda tidak mengasumsikan pengendali keadaan terbatas, ini mungkin tidak berlaku, tetapi Anda harus memikirkan ke mana perginya bit dalam proses decoding / pengenalan.
Jika Anda hanya ingin efisiensi yang lebih baik daripada 1 dari 256 byte, Anda dapat menggunakan bit 1-bit apa pun yang akan Anda gunakan untuk skema UUID Anda. Itu 1 dari 2 ^ bit-panjang inefisiensi.
Perhatikan bahwa ada skema penyandian lainnya. Pengkodean byte dengan pembatas merupakan cara termudah untuk diterapkan.
sumber
Saya sarankan memiliki array byte (atau int atau long) dan bidang panjang yang mengatakan berapa lama angkanya.
Ini kira-kira pendekatan yang digunakan oleh BigInteger Java . Ruang alamat yang dimungkinkan dari ini sangat besar - cukup mudah untuk memberikan UUID berbeda untuk setiap atom di alam semesta :-)
Kecuali Anda memiliki alasan yang sangat baik untuk melakukan sebaliknya, saya sarankan hanya menggunakan BigInteger secara langsung (atau yang setara dalam bahasa lain). Tidak ada kebutuhan khusus untuk menemukan kembali roda angka besar ....
sumber
Pertama-tama, terima kasih kepada semua orang yang memberikan jawaban yang bagus untuk pertanyaan saya yang relatif kabur dan abstrak.
Saya ingin berkontribusi jawaban potensial yang saya pikirkan setelah memikirkan jawaban lain. Itu bukan jawaban langsung untuk pertanyaan yang diajukan, tetapi itu relevan.
Seperti yang ditunjukkan beberapa orang, menggunakan integer ukuran 64/128/256 bit sudah memberi Anda ruang yang sangat besar untuk UUID. Jelas itu tidak terbatas, tetapi ...
Mungkin itu mungkin ide yang baik untuk hanya menggunakan ukuran tetap int (katakanlah, 64-bit untuk memulai) sampai 64-bit tidak cukup (atau dekat dengan itu). Kemudian, dengan anggapan Anda memiliki akses ke semua instance UUID sebelumnya, tingkatkan saja semuanya ke int 128-bit dan anggap itu sebagai ukuran tetap bilangan bulat Anda.
Jika sistem memungkinkan jeda / gangguan layanan, dan karena operasi "membangun kembali" seperti itu harus terjadi sangat jarang, mungkin manfaatnya (sistem yang sangat sederhana, cepat, mudah diimplementasikan) akan mengatasi kerugiannya (harus membangun kembali semua bilangan bulat yang sebelumnya dialokasikan ke ukuran bit integer baru).
sumber