Algoritme pencarian biner asli dalam JDK menggunakan bilangan bulat 32-bit dan memiliki bug overflow jika (low + high) > INT_MAX
( http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html ) .
Jika kita menulis ulang algoritma pencarian biner yang sama menggunakan integer 64-bit (ditandatangani), dapatkah kita berasumsi bahwa low + high
tidak akan pernah melebihi INT64_MAX karena secara fisik tidak mungkin memiliki memori 10 ^ 18 byte?
Saat menggunakan bilangan bulat 64-bit yang ditandatangani untuk mewakili kuantitas fisik , apakah masuk akal untuk mengasumsikan underflow dan overflow tidak dapat terjadi?
design
algorithms
Siqi Lin
sumber
sumber
Jawaban:
Jawaban singkatnya adalah tidak. Namun, untuk beberapa aplikasi anggapan Anda mungkin benar.
Dengan asumsi int yang ditandatangani, 2 ^ 63, dengan koma ditambahkan untuk kejelasan, = 9.223.372.036.854.775.808. Jadi kira-kira 9 * 10 ^ 18. 10 ^ 18 adalah "Exa".
Wikipedia mengatakan "Pada 2013, World Wide Web diperkirakan telah mencapai 4 zettabytes. [12]", yaitu 4000 Exabytes. Oleh karena itu, WWW kira-kira 400 kali lebih besar dari 2 ^ 63 byte.
Oleh karena itu, setidaknya ada satu kuantitas fisik yang jauh lebih besar daripada integer 64 bit yang ditandatangani (atau tidak ditandatangani). Dengan asumsi bahwa unit Anda adalah byte . Jika unit Anda adalah sesuatu yang jauh lebih besar, seperti GigaBytes, maka Anda akan baik-baik saja, tetapi ketepatan pengukuran Anda akan rendah.
Sebagai contoh lain, pertimbangkan galaksi jauh. Galaksi Andromeda sebenarnya adalah salah satu yang paling dekat, dan berjarak 2,5 * 10 ^ 6 tahun cahaya. Jika unit Anda adalah mil , itu akan menjadi 14,5 * 10 ^ 18, lebih dari 64 bit integer yang ditandatangani. Sekarang, jelas itu tergantung pada unit yang Anda gunakan untuk pengukuran Anda, tetapi beberapa galaksi jauh lebih jauh dari Andromeda. ( Yang terjauh yang diketahui berjarak 13 * 10 ^ 9 LY. ) Tergantung pada presisi yang Anda inginkan untuk pengukuran Anda, bisa meluap bilangan bulat 64 bit.
( Ditambahkan ) Ya, mil adalah unit yang buruk untuk jarak astronomi. Satuan yang lebih normal mungkin adalah Satuan Astronomi , kira-kira 93 juta mil. Dengan menggunakan satuan pengukuran itu, galaksi terjauh yang diketahui kira-kira 10 ^ 15 AU (jika matematika saya benar), yang akan cocok dengan int 64 bit. Namun, jika Anda ingin juga mengukur jarak ke Bulan, ke satelit yang mengorbit di dekatnya, satuan itu terlalu besar.
Satu lagi contoh dari elektronik: Farad (F), unit kapasitansi . Kapasitor besar berkisar hingga 5kF. Dan jumlah ini kemungkinan akan meningkat seiring waktu seiring dengan meningkatnya mobil Hybrid, "smart grids", dll. Sekali dapat mengukur kapasitansi sekecil 10 ^ -18 F. Jadi kisaran keseluruhan dalam kapasitansi "nyata" yang dapat kita ukur hari ini adalah 5 * 10 ^ 21, lebih besar dari integer 64 bit.
sumber
Anda bahkan tidak perlu menjadi kosmik ketika kombinatorik terlibat. Ada 2 ^ 95 kemungkinan transaksi dalam permainan bridge dan itu ada di sisi kecil kompleksitasnya.
sumber
Kuantitas fisik yang paling relevan untuk pertanyaan Anda adalah RAM komputer .
Windows Server 2012 mendukung hingga 4 TB memori fisik. Itu 2 42 byte. Jika kapasitas RAM terus bertambah dua kali lipat setiap tahun, maka hanya dalam 17 tahun dari sekarang "Windows Server 2032" akan mendukung 2 62 byte memori fisik, pada saat itu Anda
low + high
akan mencapai 2 63 - 2 dan mencium maksimum 64-bit integer yang ditandatangani.Saya harap tidak ada sistem yang kritis terhadap keselamatan gagal, mengasumsikan 64 bit akan selalu cukup.
Untuk penggunaan yang sedikit lebih umum, kuantitas fisik yang paling relevan adalah ruang alamat memori . (Ini berguna untuk memiliki ruang alamat yang jauh lebih besar daripada memori fisik, misalnya untuk meletakkan banyak tumpukan dalam memori, semua dengan ruang untuk tumbuh.) Implementasi x86-64 saat ini mendukung alamat virtual 48 bit, jadi kami hanya memiliki 14 tahun sebelum CPU ini mencapai batas ruang alamat 2 62 byte.
Dan kemudian ada memori bersama yang didistribusikan "di mana memori (terpisah secara fisik) dapat dialamatkan sebagai satu ruang alamat (dibagikan secara logis)".
sumber
0xFFFFFFFFxxxxxxxx
(yaitu separuh lebih tinggi ), misalnya sistem operasi atau driver perangkat.Tidak persis. Ada banyak angka yang keduanya lebih besar dan lebih kecil dari itu, itulah sebabnya kami memiliki angka floating point. Angka titik apung memperdagangkan presisi yang lebih rendah untuk rentang yang lebih baik.
Dalam contoh spesifik yang Anda kutip, sangat tidak mungkin bahwa Anda akan membutuhkan angka yang lebih besar dari itu. 64 bit sesuai dengan sekitar 18 trilyun elemen. Tapi jangan pernah bilang tidak pernah.
sumber
Asumsi Anda tidak akan menangani jumlah fisik yang hanya dapat diwakili oleh angka floating point. Dan bahkan jika Anda memutuskan untuk menskalakan semua angka, katakanlah dengan mengalikan semua angka dengan 10.000 (sehingga nilainya masih bilangan bulat tetapi dapat direpresentasikan dalam sepuluh per seribu), skema ini masih gagal untuk angka yang sangat mendekati nol, misalnya massa elektron (9.1094 * 10⎻³¹ kg).
Itu adalah kuantitas fisik yang sangat nyata (dan sangat kecil) , di sini ada beberapa lagi yang akan membuat Anda kesulitan. Dan jika Anda berpendapat bahwa itu bukan kuantitas fisik nyata (meskipun dalam kg), pertimbangkan:
Jadi Anda lihat ke mana saya akan pergi dengan ini. Yang terakhir tidak bisa Anda tangani juga.
Tentu saja, Anda bisa memiliki bidang khusus dalam angka untuk skala bagian integer naik atau turun dengan pengali variabel; Wah sekarang Anda baru saja menciptakan floating point.
sumber
Pertama saya akan menjawab pertanyaan nilai fisik apa yang bisa / harus diwakili oleh bilangan bulat?
Integer adalah representasi dari bilangan alami (dan perbedaan di antara mereka) dalam sistem komputer, jadi menerapkannya pada hal lain adalah salah. Dengan demikian, memohon jarak atau jumlah lain yang termasuk dalam domain kontinu bukan argumen. Untuk jumlah seperti itu ada representasi bilangan real. Dan Anda selalu dapat memilih unit besar dan cocok dengan nilai apa pun dengan presisi yang diberikan.
Jadi apa saja nilai fisik yang merupakan bilangan asli dan dapatkah mereka melimpah bilangan bulat 64bit?
Saya bisa memikirkan dua. Jumlah objek fisik (seperti atom), dan tingkat energi yang dapat dimasukkan oleh sistem kuantum. Itu adalah dua hal yang benar-benar bilangan bulat. Sekarang, saya tahu Anda dapat membagi atom, tetapi masih menghasilkan jumlah integer dan Anda tidak dapat membaginya tanpa batas. Keduanya dapat dengan mudah melampaui kisaran integer 64bit yang tidak ditandai . Jumlah atom lebih tinggi, dan satu atom dapat lebih dari satu energi.
Apakah informasi itu fisik atau bukan, sangat bisa diperdebatkan. Saya akan mengatakan tidak. Karena itu, saya tidak akan mengatakan bahwa jumlah informasi adalah hal yang fisik. Jadi bukan jumlah RAM atau semacamnya. Jika Anda mengizinkan ini, maka jumlah atom dengan mudah melampaui angka ini, karena Anda membutuhkan lebih dari satu atom untuk menyimpan satu bit dengan teknologi saat ini.
sumber
Selain jawaban Jerry101, saya ingin menawarkan tes yang sangat sederhana dan praktis ini untuk kebenaran:
Misalkan Anda mengalokasikan sebagian memori melalui
malloc
, dalam OS 64-bit. Misalkan pengalokasi memori memutuskan untuk kembali kepada Anda blok memori yang valid, dari ukuran yang Anda minta, tetapi di mana bit ke-63 diatur.Dengan kata lain, anggap saja ada beberapa lingkungan pemrograman di mana
0xFFFFFFFFxxxxxxxx
rentang memori yang sah yang mungkin dikembalikan dari panggilan kemalloc
.Pertanyaannya adalah, apakah kode Anda masih berfungsi sebagaimana dimaksud?
Ketika situasi analog terjadi pada sistem operasi 32-bit, beberapa perangkat lunak tidak beroperasi dengan benar jika mereka diberikan alamat memori "di bagian atas". Awalnya, alamat memori tersebut dianggap hanya tersedia untuk kode istimewa (sistem operasi, driver perangkat, dan perangkat keras periferal), tetapi karena krisis ruang alamat 32-bit, vendor OS memutuskan untuk membuat bagian dari ruang yang disediakan untuk tersedia aplikasi yang memintanya.
Untungnya, situasi ini sangat tidak mungkin terjadi untuk program 64-bit untuk sementara waktu, setidaknya tidak dalam satu dekade.
Ketika situasi itu akhirnya terjadi, itu berarti bahwa prosesor 128-bit yang dapat dialamatkan dan sistem operasi akan menjadi arus utama pada saat itu, dan bahwa mereka akan dapat menyediakan "lingkungan emulasi 64-bit" untuk memungkinkan "aplikasi warisan" untuk beroperasi dengan asumsi yang mirip dengan sistem operasi 64-bit saat ini.
Akhirnya, perhatikan bahwa diskusi ini hanya berfokus pada alamat memori. Masalah serupa dengan cap waktu harus diambil dengan lebih hati-hati, karena format cap waktu tertentu mengalokasikan banyak bit presisi ke mikrodetik, dan karena itu menyisakan bit lebih sedikit tersedia untuk mewakili waktu di masa depan. Masalah-masalah ini dirangkum dalam artikel Wikipedia tentang masalah Tahun 2038 .
sumber
Ini adalah pertanyaan yang perlu Anda tanyakan berdasarkan kasus per kasus. Anda tidak boleh menggunakan asumsi umum bahwa aritmatika 64-bit tidak akan meluap, karena bahkan ketika jumlah yang benar akan berada dalam kisaran yang jauh lebih kecil, sumber data jahat dapat berakhir memberi Anda jumlah yang tidak masuk akal yang bisa meluap, dan lebih baik menjadi siap untuk situasi ini daripada dihantam secara tak terduga.
Ada beberapa kasus di mana masuk akal untuk menulis kode yang tergantung pada non-overflow angka 64-bit. Kelas utama dari contoh yang saya tahu adalah penghitung, di mana penghitung bertambah setiap kali digunakan. Bahkan pada tingkat satu peningkatan per nanosecond (tidak praktis) akan membutuhkan lebih dari satu abad untuk meluap.
Perhatikan bahwa walaupun pada awalnya mungkin tampak "selalu salah pada prinsipnya" untuk mengandalkan "waktu sampai kegagalan" untuk kebenaran suatu sistem, kami melakukan ini sepanjang waktu dengan otentikasi / login. Diberi cukup waktu (untuk kekerasan), sistem seperti itu (apakah berdasarkan kata sandi, kunci pribadi, token sesi, dll.) Rusak.
sumber
Apakah mungkin jumlah fisik tidak muat dalam 64 bit? Tentu saja. Yang lain menunjukkan penghitungan jumlah atom di matahari atau jumlah milimeter ke galaksi berikutnya. Apakah kasus semacam itu relevan dengan aplikasi Anda tergantung pada apa aplikasi Anda. Jika Anda menghitung jumlah item di nampan tertentu di gudang Anda, 16 bit kemungkinan akan cukup. Jika Anda mengumpulkan statistik tentang jumlah orang di dunia yang memenuhi berbagai persyaratan, Anda harus dapat merekam miliaran, sehingga Anda akan membutuhkan lebih dari 32 bit, pada titik mana Anda mungkin akan mencapai 64 (karena beberapa komputer memiliki dukungan bawaan untuk 37 angka bit, dll). Jika ini adalah aplikasi kimia yang menghitung atom mol, 64 bit tidak akan cukup.
Secara teknis, hanya karena tidak ada komputer saat ini memiliki 2 ^ 64 byte memori tidak berarti indeks array tidak akan pernah lebih dari 2 ^ 64. Ada konsep yang disebut "array jarang" di mana banyak elemen array tidak disimpan secara fisik di mana pun, dan nilai yang tidak disimpan tersebut dianggap memiliki beberapa nilai default seperti nol atau nol. Tapi saya kira bahwa jika Anda menulis fungsi untuk mencari array atau daftar sejenis, dan ukuran bidang yang Anda gunakan untuk menahan indeks ke dalam array lebih dari dua kali lipat kemungkinan alamat terbesar, kemudian memeriksa untuk meluap ketika menambahkan dua indeks tidak akan sepenuhnya diperlukan.
sumber
Tidak masuk akal untuk menganggap integer 64 bit dapat menampung semua angka. Berbagai alasan:
Bilangan bulat maks dan min 64 bit adalah angka terbatas. Untuk setiap nomor hingga, ada sejumlah terbatas dan lebih kecil.
Perhitungan dengan angka 128 bit dan 256 bit saat ini digunakan di berbagai tempat. Banyak prosesor memiliki instruksi spesifik yang beroperasi pada bilangan bulat 128 bit.
20 tahun yang lalu, disk 1 GB dianggap "besar". Saat ini disk 1 TB dianggap kecil. 20 tahun yang lalu desktop rata-rata memiliki sekitar 16 MB RAM. Desktop saya saat ini memiliki lebih dari 16 GB RAM. Ruang harddisk dan RAM telah tumbuh secara eksponensial di masa lalu, dan diperkirakan akan tumbuh secara eksponensial di masa depan. Kecuali jika seseorang dapat mengemukakan alasan yang sangat bagus mengapa ia harus berhenti tumbuh, tidak masuk akal untuk menganggapnya akan berhenti.
sumber