Mengapa komputer dihitung dari nol?


55

Komputer secara tradisional menghitung nilai numerik mulai dari nol. Misalnya, array dalam bahasa pemrograman berbasis C mulai dari indeks nol.

Apa alasan historis yang ada untuk ini, dan keuntungan praktis apa yang dihitung dari nol memiliki lebih dari satu menghitung?

Catatan: Pertanyaan ini menanyakan jawaban teknis yang dijelaskan dengan baik, bukan hanya pendapat, dan dimaksudkan untuk mencakup komputer secara umum, bukan hanya pemrograman. Pertanyaan ini berkembang pada pertanyaan Programmer "Mengapa struct / array berbasis nol?" .



9
Ada lebih dari beberapa contoh bahasa komputer yang menggunakan array 1-asal.
Daniel R Hicks

23
Mengapa manusia tidak dihitung dari 0?
Tanpa judul

47
Woah, wah, tidak ada yang dihitung dari nol, kami indeks dari nol. Tidak ada yang mengatakan elemen "nol". Kita mengatakan elemen "pertama" pada indeks 0. Pikirkan indeks seberapa jauh suatu elemen diimbangi dari posisi pertama. Nah, elemen pertama ada di posisi pertama, jadi tidak diimbangi sama sekali, jadi indeksnya adalah 0. Elemen kedua sebagai satu elemen sebelumnya, jadi itu mengimbangi 1 elemen dan berada di indeks 1
mowwwalker

14
@Ramhound Tidak, tidak. Pengindeksan berbasis nol sama sekali tidak terkait dengan menggunakan biner.
Peter Olson

Jawaban:


88

Menghitung array dari 0 menyederhanakan perhitungan alamat memori setiap elemen.

Jika array disimpan pada posisi tertentu dalam memori (disebut alamat), posisi setiap elemen dapat dihitung sebagai

element(n) = address + n * size_of_the_element

Jika Anda menganggap elemen pertama sebagai yang pertama, perhitungannya menjadi

element(n) = address + (n-1) * size_of_the_element

Bukan perbedaan besar tetapi menambahkan pengurangan yang tidak perlu untuk setiap akses.

Sunting

  • Penggunaan indeks array sebagai penyeimbang bukan keharusan, tetapi hanya kebiasaan. Offset elemen pertama dapat disembunyikan oleh sistem dan dipertimbangkan ketika mengalokasikan dan mereferensikan elemen.

  • Dijkstra menerbitkan sebuah makalah "Mengapa penomoran harus dimulai dari nol" ( pdf ) di mana ia menjelaskan mengapa memulai dengan 0 adalah pilihan yang lebih baik. Mulai dari nol memungkinkan representasi rentang yang lebih baik.


8
+1 untuk jawaban yang benar. Perhatikan bahwa pengindeksan berbasis 0 hanyalah konvensi (sangat umum) dari bahasa yang digunakan; itu tidak universal. Misalnya, Lua menggunakan pengindeksan berbasis 1 . "Pengurangan yang tidak perlu" mungkin menjadi alasan di balik pengindeksan berbasis 0 di masa lalu, tapi sekarang sebagian besar bahasa menggunakannya hanya karena itu adalah apa yang semua orang sudah terbiasa (sebagian besar berkat C) , dan tidak ada alasan kuat untuk mengubah itu Konvensi.
BlueRaja - Danny Pflughoeft

2
Ini tidak masuk akal. Posisi setiap elemen selalu dapat dihitung address + n * size_of_elementselama "alamat" adalah alamat dari elemen nol. Ini berfungsi dengan baik apakah elemen nol ada sebagai elemen array atau tidak. Pertanyaannya adalah mengapa elemen zeroth ada, bukan mengapa kami menyimpan alamat sebagai alamat dari elemen zeroth (mungkin notional). (Yang menjawab ini.)
David Schwartz

3
@ DavidSchwartz Mari kita mengambil bahasa lama sebagai C. Jika mengalokasikan memori Anda mendapatkan alamat di mana memori dimulai. Jika kompilator melihat sesuatu seperti v[n]itu harus menghitung alamat ekspresi. Jika indeks memulai 0 perhitungannya adalah ukuran v + x *. Jika pada 1 perhitungan adalah ukuran v + (x-1) *. Misalnya, v [1] akan sesuai dengan v + (1-1) * ukuran yaitu v.
Matteo

4
@ David: Dalam C (bahasa yang benar-benar mempopulerkan pengindeksan berbasis 0) , array dan pointer sebagian besar tidak dapat dipertukarkan, jadi penting untuk sejumlah alasan yang *arraysebenarnya merujuk pada elemen pertama. Salah satu contoh: jika kita arraymenunjuk ke lokasi memori sebelum elemen pertama, casting ke array dari tipe yang berbeda akan menyusahkan misalnya. posisi byte kedua dalam array ints akan menjadi tergantung pada ukuran kata; pada mesin 32-bit, itu akan di ((char*)intArray + 5)!!
BlueRaja - Danny Pflughoeft

3
Tidak, ini bukan masalah apakah array memiliki elemen nol. Karena, Anda lihat, ada juga penskalaan. Jika saya memiliki array objek 8 byte, dan saya overlay dengan array byte, berapakah indeks byte objek [42]? Mengapa ini sederhana: 42 * 8. Masalah dengan 1 berbasis adalah bahwa offset 1 ini adalah 1 byte ketika saya melihat array byte, dan itu adalah 8 byte ketika saya melihat array 8-byte-unit overlay.
Kaz

38

Sementara prinsip-prinsip di bawah ini berlaku untuk desimal dan juga basis lainnya, Menghitung dari 0 di komputer dapat dengan mudah dipahami secara alami dari sistem biner digit-tetap untuk mewakili angka yang digunakan dalam komputer. Jika Anda memiliki 8 bit, maka ada 256 kemungkinan kombinasi 1s dan 0s yang dapat diekspresikan. Anda bisa menggunakan 8-bit ini untuk mengekspresikan angka 1-256, tetapi ini akan meninggalkan 0 yang berguna dalam matematika sebagai bilangan dalam dan dari dirinya sendiri, sehingga mereka digunakan untuk mengekspresikan angka 0-255.

Ini sudah menetapkan preseden dari tatanan alam mulai dari 0 (semua 0 di representasi biner) ke 255 (semua 1 di nomor 8-bit). Mempertimbangkan sistem yang mewakili angka, mulai dari 0 masuk akal karena 0 adalah angka "pertama" dalam sistem, jadi 1 adalah angka "kedua", dan seterusnya.

Alasan tambahan mengapa mulai dari 0 di komputer sangat nyaman adalah karena konsep offset. Offset adalah angka yang menunjukkan jarak dari lokasi dalam memori atau hard disk atau media "yang dapat dialamatkan" lainnya. Di komputer, secara praktis semua data disimpan secara linear, artinya ada urutan data, byte pertama, byte kedua, dll. Lebih mudah untuk menyatakan lokasi "area" data melalui offset. Apa byte pertama dalam satu blok data? Itu di offset '0', yang berarti ditemukan 0 byte setelah byte pertama dalam blok data. Meskipun dimungkinkan untuk memiliki "1" menunjuk byte pertama, ini menciptakan komplikasi dalam representasi data karena beberapa alasan:

  • Dengan mengecualikan 0 dari yang digunakan untuk menangani data, Anda mengurangi jumlah hal yang dapat Anda atasi dengan nomor 8-bit per satu.
  • Untuk menghitung offset, yang diperlukan pada tingkat hardware akses data, pada titik tertentu Anda harus mengurangi satu dari penomoran, yang memperkenalkan kompleksitas.
  • Pointer ke blok data selalu mengarah ke blok pertama, jadi aritmatika langsung ketika Anda mulai dari 0. (yaitu, byte pertama di blok pertama dari cluster data pertama adalah 0 + 0 + 0 saat Anda mulai dari 0 , itu adalah 1 + 1 + 1 - 1 -1 ketika Anda mulai dari 1.) Aritmatika untuk ini ketika Anda mulai dari 1 dengan struktur data bersarang seperti contoh ini dapat membingungkan.

31
Tidak ada hubungannya dengan representasi biner. Bilangan biner dan desimal dimulai dari 0.
Matteo

2
Jika Anda mulai menghitung dari 0 Anda tidak mengurangi jumlah alamat yang Anda dapat (secara teori) berubah dari 1 menjadi 257.
Matteo

6
@ Matteo tidak dalam satu byte Anda tidak bisa
Stop Harming Monica

8
@Dougvj Penghitungan berbasis nol sama sekali tidak ada hubungannya dengan biner. Poin yang Anda sampaikan adalah tentang memanfaatkan setiap angka dalam representasi angka tetap, yang merupakan masalah terlepas dari apakah Anda menggunakan basis 2, basis 10, atau basis 23517.
Peter Olson

2
-1 Ini sama sekali tidak ada hubungannya dengan representasi biner.
BlueRaja - Danny Pflughoeft

26

Tidak pernah terpikir kesempatan bagi filsuf kursi seperti saya akan datang bersama Superuser. Ada kesalahpahaman mendasar di hati di sini, karena non-filsuf cenderung melewatkan rincian menit. Singkatnya: Komputer tidak dihitung dari nol, tetapi denominasi posisi dimulai dari nol.

Tidak ada yang membingungkan tentang persepsi inkonsistensi antara komputer dan teknik penghitungan manusia. Mari kita uraikan pertanyaannya.

Mengapa komputer dihitung dari nol?

  • Mereka tidak dihitung dari nol

Nilai penghitungan komputer mulai dari nol. Misalnya, array dalam C.

  • The Indeks (indikator posisi, penghitungan) dimulai dari nol. The hitungan elemen dalam array di mana ada satu elemen pada indeks nol adalah salah satu

Nol praktis untuk mewakili kekosongan sesuatu atau titik tengah skala. Tidak praktis untuk menghitung apa pun karena tidak mungkin dengan definisi nol.

Dalam arti yang sama dengan titik tengah skala, nol dapat digunakan untuk mewakili ujung (awal absolut) koleksi. Pertanyaannya tidak ada artinya karena tidak konsisten antara "nilai penghitungan" dan "dihitung dari nol".

Jadi ya, komputer menghitung dari nol, tetapi mereka dihitung dari satu. Kedua kata tersebut memiliki arti yang berbeda.

tal·ly [tal-ee]

kata benda

  1. akun atau perhitungan; catatan debit dan kredit, skor permainan, atau sejenisnya.
  2. apa pun di mana skor atau akun disimpan ..
  3. sejumlah atau kelompok barang yang direkam.

hitung [kount]

kata kerja (digunakan dengan objek)

  1. untuk memeriksa (unit atau kelompok koleksi yang terpisah) satu per satu untuk menentukan jumlah total; menjumlahkan; enumerate: Dia menghitung tiketnya dan mendapati dia punya sepuluh.
  2. untuk diperhitungkan; menghitung; menghitung.
  3. untuk daftar atau nama angka hingga: Tutup mata Anda dan hitung sepuluh.

(dictionary.com)


Alasan praktis dijelaskan secara memadai oleh Dougvj, saya tidak perlu menambahkan apa pun di sana. Kalau saja kita bisa memiliki profesor CS (dari 60-an) untuk memberikan akun sejarah ...


Bahkan, bagaimana Anda tahu di mana komputer memulai sesuatu? Yang Anda tahu adalah bahwa, ketika Anda menggunakannya, Anda KATAKAN untuk mulai dari nol.
Daniel R Hicks

Saya berbicara definisi konsep dan logika di sini, bukan bagaimana komputer bekerja sendiri. Saya tahu sedikit tentang di mana komputer memulai sesuatu karena saya telah mengambil kursus CS.
Ярослав Рахматуллин

1
Untuk menjadi benar-benar hebat, Anda membandingkan kata kerja dengan kata benda. Saya pikir "tally" dan "count" benar-benar sama, dan keduanya dapat digunakan sebagai kata kerja atau kata benda.
Brian

1
@ Brian Pengamatan yang adil dan dan maksud saya adalah untuk menggambarkan (dengan cara yang pedantic) bahwa kebingungan berasal dari salah tafsir istilah. Sebenarnya tidak ada perbedaan antara "elemen 1" dan "elemen di posisi 0". Keduanya adalah elemen satu. Yang pertama , bukan " nol ". Tidak ada yang namanya menghitung dari nol . Pencacahan dimulai dari satu dengan definisi, sedangkan pengalamatan mungkin a-> 1, b-> 2. c-> 3 atau 0-> 1, 1-> 2, 2-> 3. Contoh paling umum dari "menghitung dari nol" dapat ditemukan di buku matematika sekolah menengah dalam bentuk {x₀, x₁, x₂} - tetapi subskripnya adalah sebuah indeks .

1
Hanya saja desainer sebenarnya berkeliaran sedikit sebelum mereka memutuskan skema saat ini. Apa yang tampak "jelas" sekarang tidak. Dan kemungkinan skema yang agak berbeda bisa dipilih dan sekarang akan tampak lebih "jelas" daripada apa yang kita miliki.
Daniel R Hicks

12

Saya pikir ini telah dibahas sebelumnya oleh " prof.dr. Edsger W. Dijkstra " - Burroughs Research Fellow dalam surat tertanggal 11 Agustus 1982: cf EWD831

Berjudul: Mengapa penomoran harus dimulai dari nol . "Apakah ada alasan untuk lebih memilih satu kebaktian daripada yang lain? Ya, ada ...."

Perhatikan juga bahwa Dijkstra berada di tim desain ALGOL 68 hingga 1968. Algol68 mengizinkan array baik dari 0, 1 atau nomor apa pun yang dianggap tepat oleh programmer untuk algoritme. cf ( "The Making of Algol 68" menceritakan '"Bisakah Anda mendefinisikan array segitiga?" seseorang (Tony Hoare?)) memotong, "Bukan hanya segitiga, tetapi bahkan elips" jawab Aad, dan menunjukkan caranya.')

Secara khusus, di Algol68, ketika array (& matriks) diiris mereka mendapatkan indeks @ 1, jadi ada bias terhadap array [1: ...]. Tetapi batas bawah "1 st " dapat dipindahkan untuk mulai dari posisi "0 th " dengan menentukan "@ 0", mis. Vektor x [4: 99 @ 2], matriks y [4: 99 @ 1,4: 99 @ 0]. Demikian pula ada default / bias dari 1 di do ~ od loop (kecuali " dari 0" secara eksplisit dinyatakan), dan dari 1 untuk kasus integer i di ~, ~, ~ esac dan $ c (~, ~, ~ ) $ pilihan klausa.

Tampaknya komentar Dijkstra tentang Draft Report ( MR93 ) Maret 1968 dan desakannya memprovokasi apa yang bisa dikatakan sebagai perang api pra-usenet : "ada tulisan-tulisan yang dapat dicintai meskipun tanpa tata bahasa, dan ada tulisan-tulisan lain yang sangat gramatikal, tetapi menjijikkan. Ini adalah sesuatu yang saya tidak bisa jelaskan kepada orang yang dangkal. " EWD230

Laporan Akhir Algol 68 (FR) keluar pada tanggal 20 Desember 1968 ketika dibenci di Pertemuan Munich dan kemudian diadopsi oleh Kelompok Kerja. Selanjutnya laporan disetujui oleh Majelis Umum IFIP UNESCO untuk publikasi.

Sekitar 23 Desember (?) 1968 Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger dan Garwick menandatangani AB31.1.1.1 "Laporan Minoritas", halaman 7 (Diterbitkan 1970).


10

Analogi jarak yang dibawa orang lain cocok dengan ilustrasi yang sangat praktis:

"Seberapa jauh rumahmu dari pompa bensin terdekat?"

"1 mil."

"Kamu tinggal di pompa bensin?"

"Tidak, jika aku tinggal di pompa bensin itu akan 0 mil"

"Mengapa kamu menghitung dari nol, bukan dari satu?"

Contoh bagus lainnya adalah ulang tahun - kita tidak mengatakan seseorang berumur satu tahun pada hari mereka dilahirkan, kita mengatakan itu setahun kemudian.

Kami mengatakan tahun kabisat atau pemilihan presiden AS setiap empat tahun, meskipun jika Anda hitung dari satu: 2000 , 2001, 2002, 2003, 2004 adalah lima tahun. (Kebetulan, Romawi memang mengacaukannya untuk sementara waktu, dan telah melompati tahun terlalu dekat)

Maksud saya adalah, kita "menghitung" dari nol sepanjang waktu di dunia nyata - "Berapa banyak posisi setelah [awal susunan] adalah elemen yang Anda inginkan" adalah pertanyaan yang Anda jawab dengan hitungan-dari-nol dalam banyak program komputer. Anda tidak akan mengatakan bahwa elemen pertama adalah satu posisi setelah awal, bukan? Ini adalah awal.


1
Matematika Anda tentang pemilihan dimatikan satu tahun. Contoh Anda berisi 2 tahun pemilihan dalam rentang 5 tahun; ilustrasi yang tepat adalah bahwa 4 tahun berlalu dari satu pemilihan ke pemilihan berikutnya, yaitu 2000 -> 2001 (rentang 1 tahun), 2001 -> 2002, 2002 -> 2003, 2003 -> 2004.
Jimmy

1
@ Jimmy Itulah maksud saya - jika orang "menghitung dari satu" dalam arti mereka menginginkan komputer, mereka akan menghitung 2000 sebagai satu dan bukan nol. Ini adalah, kebetulan, bagaimana Romawi kuno benar-benar melakukannya (dan memang akan menggambarkan siklus seperti "2000, 2004, 2008" sebagai siklus lima tahun).
Random832

2
Contoh ulang tahun Anda tidak sepenuhnya benar secara universal. Misalnya, di Korea Selatan tahun pertama kehidupan dihitung sebagai satu dan bukan nol .
BennyMcBenBen

6

Seperti yang sudah dikatakan oleh orang lain komputer tidak dihitung dari nol .

Beberapa bahasa mengindeks dari 0. Mengindeks dari 0 memiliki dua keunggulan utama:

  1. Itu dikonversi ke perakitan dengan cara alami karena dapat diartikan sebagai offset dari pointer ke posisi pertama.

  2. Anda tidak mendapatkan keanehan ketika Anda menginginkan yang negatif. Berapa tahun antara 1BC dan 1AD? Tidak ada Karena walaupun BC secara efektif adalah tanggal negatif, tidak ada tahun nol. Jika ada 0AD tidak akan ada masalah di sini. Anda melihat masalah yang sama di semua tempat dalam sains di mana orang secara naif mendefinisikan elemen pertama dalam set sebagai +1.


Ya, dan seluruh kebodohan menunggu hingga tahun 2001 untuk milenium baru. Ini membingungkan orang-orang yang juga tidak "mendapatkan" array berbasis nol ketika mereka mencoba-coba pemrograman. :)
Kaz

3
Juga, jika "1 mil" berarti "di sini", maka karena satu mil adalah 1760 kaki, itu berarti bahwa "1760 kaki" juga berarti "di sini", kan? Salah, "1 kaki" artinya di sini, oops! Dalam kebodohan yang berdasarkan ini, "di sini" adalah satu kaki, satu inci, satu sentimeter, dll.
Kaz

1
@kaz di mana kaki => yard. 1760 yard dalam satu mil.
Brad

3

Menghitung secara alami dimulai dari nol

Berikut adalah algoritma untuk menghitung apel dalam keranjang:

count := 0

for each apple in basket
   count := count + 1

Setelah eksekusi di atas, counttahan jumlah apel. Mungkin nol, karena keranjang bisa kosong.

Jika Anda tidak menggunakan kartu kredit selama sebulan penuh, apakah Anda mendapat tagihan 1 dolar? Atau 1 sen?

Ketika Anda mengatur ulang meter perjalanan pada odometer mobil Anda, apakah itu menjadi 0001 atau 0000?

Array dapat memberikan banyak tampilan data yang sama

Pertimbangkan susunan struktur 32 bit d, yang masing-masing terbuat dari 16 kata bit w. Setiap kata terdiri dari dua byte 8 bit b. Di bawah pengindeksan nol, hamparan terlihat sangat nyaman:

d: |   0   |   1   |
w: | 0 | 1 | 2 | 3 |
b: |0|1|2|3|4|5|6|7|

Objek 32 bit d[1]seperti pada alamat kata w[2]yang mudah dihitung dengan mengalikan indeks dengan 2, yang merupakan rasio ukuran objek 32 dan 16 bit. Selanjutnya, dalam pengalamatan byte, itu b[4].

Ini berfungsi karena nol adalah nol, di setiap unit pengukuran: byte, kata, kata ganda dan sebagainya.

Lihat diagram di atas: ini terlihat seperti penggaris, di mana konversi satuan bersifat intuitif.

Dengan satu pengindeksan berbasis, itu rusak:

d: |   1   |   2   |
w: | 1 | 2 | 3 | 4 |
b: |1|2|3|4|5|6|7|8|

Sekarang kita tidak bisa hanya mengalikan dindeks dengan 2 untuk mendapatkan windeks, atau dengan 4 untuk mendapatkan bindeks. Konversi antar unit menjadi kikuk. Misalnya untuk beralih dari d[2]ke b[4], kita harus menghitung ((2 - 1) * 4) + 1 = 5.

Kita harus mengurangi bias sial 1 dalam dunit, kemudian melakukan penskalaan dalam sistem koordinat berbasis nol alami, dan kemudian menambahkan kembali sial 1 dalam bunit. Perhatikan bahwa ini tidak sama dengan 1! Kami mengurangi satu lebar dua kata, tetapi kemudian menambahkan satu byte lebar .

Mengubah antara berbagai tampilan data menjadi konversi seperti Celsius-Fahrenheit.

Mereka yang mengatakan bahwa array berbasis satu mudah ditangani pada tingkat implementasi, karena hanya ada pengurangan sederhana dari 1 yang membodohi diri mereka sendiri, dan Anda. Ini benar hanya jika kita tidak melakukan perhitungan penskalaan di antara tipe data yang berbeda. Penghitungan seperti itu terjadi dalam program apa pun yang memiliki tampilan data yang fleksibel (mis. Array multi dimensi juga diakses sebagai satu dimensi) atau yang memanipulasi penyimpanan: misalnya, pengalokasi memori, sistem file, atau pustaka penyangga bingkai video.

Meminimalkan Digit

Dalam basis apa pun, jika kita ingin menggunakan digit paling sedikit untuk mengimplementasikan rentang nilai yang merupakan kekuatan basis, kita harus mulai dari nol. Misalnya, dalam basis sepuluh, tiga digit sudah cukup untuk memberi kita seribu nilai berbeda dari 0 hingga 999. Jika kita mulai dari 1, kita meluap dengan hanya satu nilai, dan kita membutuhkan empat digit.

Ini penting di komputer, karena jumlah digit dalam biner diterjemahkan ke garis alamat perangkat keras. Misalnya, sebuah chip ROM dengan 256 kata di dalamnya dapat dialamatkan dari 0 hingga 255, yang membutuhkan 8 bit: 00000000 hingga 11111111. Jika ditangani dari 1 hingga 256, maka diperlukan sembilan bit. Kita harus dengan sia-sia menambahkan satu lagi jejak alamat ke papan sirkuit atau sirkuit terintegrasi. Jadi apa yang mungkin terjadi dalam praktek adalah bahwa 0 hanya akan dipanggil1 di tingkat API perangkat lunak untuk mengakses chip itu. Permintaan untuk kata 1 sebenarnya akan menempatkan 00000000 pada bus alamat 8 bit. Atau, permintaan untuk 1 akan diterjemahkan ke alamat 00000001, seperti yang diharapkan, tetapi permintaan untuk 256 akan dipetakan ke alamat 8 bit yang tidak digunakan 00000000 daripada alamat 9 bit 100000000. Kedua kludges penggigit tas ini benar-benar solusi dalam mencari masalah , dan dihindari sepenuhnya dengan secara konsisten menggunakan 0 hingga 255 di perangkat keras, dalam perangkat lunak, dan di semua antarmuka pengguna dan dokumentasi.

Pemindahan berbasis satu pada dasarnya bodoh

Pertimbangkan teori musik Barat misalnya. Kami memiliki timbangan diatonis dengan tujuh not, tetapi kami menyebut ruang yang mencakup oktaf ! Inversi interval kemudian mengikuti aturan sembilan : misalnya inversi yang ketiga adalah keenam (kurangi tiga dari sembilan). Jadi tiga angka berbeda berperan untuk sesuatu yang sangat sederhana: tujuh (catatan dalam skala), delapan (oktaf) dan sembilan (kurangi dari menjadi terbalik).

Jika tujuh not membuat septave atau heptave, dan interval berdasarkan nol, maka kita akan mengurangi dari tujuh menjadi terbalik. Semuanya berdasarkan tujuh.

Selanjutnya, interval bisa dengan mudah ditumpuk. Dalam sistem saat ini, jika kita melompat dengan seperlima dan kemudian dengan keempat lagi, dan kemudian oleh ketiga, kita tidak bisa hanya menambahkan ini. Interval yang dihasilkan adalah dua lebih sedikit. Ini bukan keduabelas, tetapi sebenarnya sepersepuluh! Pada setiap tahap, kita harus mengurangi satu. Naik seperlima dan kemudian yang keempat bukan yang kesembilan, tetapi hanya satu oktaf.

Dalam sistem musik yang dirancang dengan baik, kita bisa menambahkan interval untuk menentukan lompatan yang dihasilkan. Urutan not yang dimulai dan diakhiri pada not yang sama akan memiliki sifat yang mirip dengan hukum voltase di sekitar rangkaian: semua interval akan menambah nol.

Teori dan penulisan musik sudah usang. Sebagian besar tidak berubah sejak hari-hari menulis dilakukan dengan pena bulu oleh cahaya lilin.

Sistem berbasis satu membingungkan orang yang sama yang tidak dapat menangani array berbasis nol

Ketika tahun 2000 bergulir, banyak orang bingung mengapa milenium baru belum dimulai. Mereka yang menunjukkan bahwa itu tidak akan dimulai sampai tahun 2001 dianggap sebagai pemburu dan penjahat pesta. Lagi pula, Anda berusia 20-an ketika berusia 20 tahun, bukan? Tidak ketika Anda berusia 21 tahun. Jika Anda berpikir bahwa milenium dimulai pada 1 Januari 2000, maka Anda tidak punya hak untuk mengeluh tentang array berbasis nol dalam bahasa pemrograman apa pun. Mereka bekerja persis bagaimana Anda suka. (Tapi, ya, para pendukung perpindahan berbasis satu dan array adalah dweeb dan partai-poopers. Berabad-abad harus dimulai pada tahun XX00, dan ribuan tahun pada X000 tahun.)

Kalender bodoh, tetapi setidaknya waktu dalam sehari adalah nol

Setiap menit pada jam tangan Anda dimulai dengan: 00 detik. Setiap jam baru dimulai dengan 00:00 menit dan detik. Dan, setidaknya pada jam 24 jam, hari bergulir sekitar ketika mogok tengah malam dan kenaikan 11:59:59 hingga 00:00:00.

Jadi jika Anda ingin menghitung detik dari tengah malam untuk waktu seperti 13:53:04, Anda hanya perlu mengevaluasi 13 * 3600 + 53 * 60 + 4. Tidak ada 1penambahan atau pengurangan yang tidak keren.

Menutup kata-kata kasar tentang MIDI

Oke, ada apa dengan musisi, bahkan yang dianggap teknis?

MIDI! Ini menggunakan penomoran berbasis nol untuk program dan saluran di representasi kawat yang sebenarnya dari pesan, tetapi gigi menampilkannya sebagai 1 berdasarkan! Misalnya program 0 hingga 127 dipanggil 1 hingga 128 pada sebagian besar gigi, tetapi beberapa memanggilnya 0 hingga 127 atau bahkan memberi pengguna pilihan.

Program 71 hingga 80 dianggap sebagai "bank" dari sepuluh. Katanya tepat di pedal MIDI saya, misalnya. Footswitch diberi label dari 1 hingga 10 dan jika saya berada di bank ketujuh, mereka memilih program 71 hingga 80. Namun, beberapa perangkat atau perangkat lunak komputer menampilkan nomor program 1-128 sebagai 0 hingga 127, atau bahkan memberi pengguna sebuah pilihan! Apa yang lebih buruk: sistem berbasis satu, atau kekacauan dibuat dengan menggunakan keduanya berbasis dan nol pada saat yang sama?

Nomor saluran MIDI disebut 1 hingga 16, tetapi diwakili oleh 0 hingga 15 biner. Seolah-olah karena dendam untuk presentasi berbasis satu, beberapa gigi menggunakan dispswitch untuk mengkonfigurasi nomor saluran dan, seringkali, sakelar ini hanya menggunakan kode biner berbasis nol. Jadi jika Anda ingin saluran 3, Anda harus beralih ke 0010 (biner 2).


1

Jika saya ingat dengan benar dari kelas Konsep Bahasa Pemrograman saya ... bahasa yang diindeks 0 dan yang lainnya yang 1 indeks harus dilakukan dengan alasan historis. Algol-68, grand-daddy bahasa pemrograman sebenarnya diindeks 1, serta Fortran dan beberapa bahasa "bisnis" lainnya seperti COBOL. Namun dalam beberapa bahasa ini, Anda sebenarnya dapat menentukan secara eksplisit apa indeks awal Anda nantinya. Ada tabel yang menarik di sini .

Pada dasarnya kembali ke " Ye Olde Days " ahli matematika, ilmuwan, dan "akademisi" lainnya biasanya menggunakan bahasa yang diindeks 0, sementara pengguna bahasa seperti COBOL merasa tidak ada gunanya untuk mulai menghitung pada 0, jadi dalam bahasa-bahasa itu lebih masuk akal untuk memulai pada 1 (sepertinya kurang membingungkan).

Sekarang jika pertanyaan Anda mengacu pada mengapa sejauh mengapa komputer ( bukan bahasa ) secara alami mulai dihitung dari nol ... baik itu saya kira melekat dalam biner benar-benar: ex: 0000= nol 0001= satu ... seterusnya dan seterusnya sebagainya ...


4
Tidak ada hubungannya dengan representasi biner. Bilangan biner dan desimal dimulai dari 0 (seperti yang Anda tunjukkan pada contoh Anda).
Matteo

Nah, itu ada yang lain harus dilakukan dengan biner. Dengan empat bit, 0000 hingga 1111, Anda dapat menangani bank memori 16 kata. Jika Anda melakukannya berdasarkan satu, maka Anda memerlukan lima baris alamat untuk mewakili 0001 hingga 10.000. Atau Anda melakukan apa, misalnya, MIDI lakukan dengan nomor saluran: 0000 digunakan secara internal, tetapi antarmuka pengguna menunjukkan 1! Jika perangkat keras berbasis desimal, itu akan menjadi masalah yang sama. Tiga digit memberi Anda seribu alamat jika Anda mulai dari nol, tetapi jika Anda mulai dari 1, Anda perlu empat digit.
Kaz

1

Angka 0 dapat menunjukkan berbagai arti: nilai numerik, ordinal, alamat memori, dll.

'Indeks nol' tidak berarti programmer menghitung dari nol. Ini menunjukkan tempat pertama dari blok memori yang dialokasikan dan '0' adalah alamatnya.

Dalam C, perulangan melalui array dapat dituliskan seperti di bawah ini:

int arr[N];
for (i=0; arr[N]; ++i) {
...
}

Pekerjaan yang sama dapat dilakukan dalam C #:

Object[] arr;

for (Object o in arr) {
...
}

Saya pikir tidak ada penghitungan dalam kedua contoh.


1

Mulai dari nol praktis ketika menggambarkan jarak dari sesuatu. Jadi dalam array ini:

[4,9,25,49]

jarak dari awal array ke 25 adalah 2 - Anda harus melewati dua langkah untuk sampai ke sana. Jarak ke 4 adalah nol - Anda tidak perlu bergerak dari awal sama sekali.

Praktis untuk berpikir seperti ini ketika menambahkan jarak (atau indeks) - Saya maju satu langkah, lalu nol langkah, lalu dua langkah, di mana saya? Saya di indeks 1 + 0 + 2 = 3. Melewati tiga langkah, saya berakhir di 49 dalam array di atas.


Menghitung lantai di gedung harus benar-benar dengan cara yang sama (meskipun kami tidak melakukannya di AS) Lantai dasar harus nol karena Anda belum naik atau turun; itu posisi awal.

Namun lantai dasar adalah yang pertama kali Anda datangi. Anda mulai menghitung ketika Anda memasuki gedung, di lantai dasar, dan menambahkan saat Anda naik. Mulai dari nol masuk akal jika Anda menganggap "di dalam bangunan" sebagai keadaan default / normal / alami, yang merupakan komentar menarik tentang masyarakat perkotaan. Nol untuk permukaan tanah juga masuk akal jika banyak sub-level yang umum.

1

Ingat bagaimana angka direpresentasikan dalam komputer. Mari kita ambil bytevariabel. 0 direpresentasikan sebagai 00000000 1 dalam biner. 1 adalah 00000001. 2 adalah 00000010. Dan seterusnya.

Perhatikan bahwa angka terendah yang bytedapat disimpan oleh can adalah 0. Jika kita memulai indeks array dengan 1, maka sistem akan menjadi tidak efisien, karena kita sekarang memiliki array dengan panjang 255 bukan 256. Karena angka dalam program C mengkompilasi ke angka biner ( intBiasanya, unsigned intdalam indeks array), tampaknya wajar untuk menggunakan 0 sebagai indeks awal karena lebih efisien.

Selain itu, dalam C ++, a[p]buka hingga *(a+p*n), di mana nukuran datatype. Dengan kata lain, a[p]berarti "Beri aku elemen di indeks a+n*p". Jika pdimulai dengan 1, maka Kami akan memiliki bagian kosong / tidak terpakai pada indeks a.

1. Tentu saja, pertanyaan yang jelas "mengapa" muncul. Mengapa tidak menetapkan 00000000 to1? Sederhana: penambahan biner (dilakukan oleh kaskade unit penambah penuh) mudah di perangkat keras ketika 00000000 adalah 0. Tambahan biner merupakan bagian integral dari semua operasi aritmatika. Jika Anda menjadikannya mewakili 1, Anda harus memberi tahu kompiler untuk mengurangi 1 dari semua angka, atau Anda perlu menyulitkan sirkuit adder untuk mengurangi yang pertama dari yang ditambahkan dan memasangnya kembali ke jumlah. (perhatikan bahwa Anda tidak bisa hanya mengurangi satu nanti, karena carry bit mungkin terlibat)


@sec karena itu menjadi tidak masuk akal di tingkat perangkat keras (lihat edit)
Manishearth

1

Modulo

Satu hal yang belum dijawab oleh jawaban yang baik: pengindeksan berbasis nol bekerja dengan baik bersama dengan operasi modulo, yang karenanya dapat digabungkan untuk membentuk daftar siklik. Pikirkan misalnya tentang sesuatu seperti

color = colors[i % colors.length]

yang mungkin memberikan setiap objek (diindeks oleh i) warna yang berbeda dari daftar colors, sampai semua warna telah digunakan, pada titik mana itu akan mulai lagi dari awal. Mengekspresikan hal yang sama dalam pengindeksan satu berbasis sangat canggung:

color = colors[(i - 1) % colors.length + 1]

Operasi modulo otomatis yang dipaksakan oleh aritmatika biner ukuran tetap yang tidak ditandatangani dengan wrap-around adalah contoh lain mengapa ini masuk akal.

Melayani keduanya

Hal lain yang perlu dipertimbangkan adalah fakta bahwa cukup mudah untuk tidak menggunakan elemen pertama dari array berbasis nol. (Ini tidak berlaku untuk foreachiterasi gaya dan konstruksi bahasa serupa yang memperlakukan array secara keseluruhan.) Banyak programmer, termasuk saya sendiri, mungkin merasa sedikit canggung tentang ruang yang terbuang, tetapi dalam kebanyakan situasi jumlahnya sangat kecil sehingga kekhawatiran ini tidak berdasar. Di sisi lain, jika bahasa menggunakan pengindeksan berbasis satu, maka tidak ada cara untuk mensimulasikan elemen pada indeks nol tanpa banyak kode. Jadi mengingat bahwa dalam beberapa situasi pengindeksan berbasis nol lebih baik daripada berbasis satu, memilih nol sebagai basis di mana-mana adalah pendekatan yang lebih fleksibel, tidak seperti berbasis satu tempat, dan juga lebih konsisten daripada posisi awal yang dapat dikonfigurasi.


0

Sistem komputer menggunakan bilangan asli (dihitung dari 0) dan bilangan bulat (dihitung dari 1). Orang menghitung hal-hal dalam bilangan bulat, yang membuatnya menjadi intuitif untuk daftar penomoran, dan banyak bahasa pemrograman mengambil keuntungan dari itu: BASIC, COBOL, Fortran, Lua, dan Pascal semuanya dihitung dari 1. Bahasa-bahasa tersebut menargetkan ceruk seperti pemrosesan data, analisis numerik, dan pengajaran, di mana daftar sederhana, intuitif adalah keuntungan.

Seluruh angka menjadi canggung ketika Anda mulai menganalisis dan memanipulasi struktur data, alih-alih hanya memproses semuanya secara berurutan. Bila Anda perlu merujuk ke urutan dalam rumus atau algoritma, lebih mudah dan kurang rawan kesalahan ke nomor mereka dari 0, seperti matematika lakukan: a 0 , a 1 , a n , dll Jika tidak, Anda harus sering menyesuaikan dengan 1 dan –1 untuk mendapatkan data yang benar, dan mudah salah, menciptakan bug. Oleh karena itu, bahasa yang dirancang untuk ilmuwan komputer biasanya menggunakan bilangan asli: C, Java, dan Lisp semuanya dihitung dari 0.

Di luar bahasa pemrograman, banyak sistem komputer yang menghitung mulai dari 0 karena itulah yang biasa digunakan para ilmuwan komputer. Juga, karena penomoran dari 1 mengarah ke begitu banyak bug berbahaya, banyak dari kita menghindarinya di luar elemen antarmuka yang dirancang khusus untuk pengguna akhir non-teknis.


Java ... untuk para ilmuwan komputer. LOL!
Kaz

0

Jawaban sederhananya adalah bahwa angka pertama bukan 1, melainkan 0.

Penjelasan: Rumus untuk menghitung angka multi-digit pada basis apa pun adalah:

n = sum(i=0 to n, Di^i)

WHERE 
n = numeric result
i = index (starting with 0)
Di = is the digit at index i

Mari kita ambil sistem desimal, yang paling sering kita gunakan.

Melihat nomor 1234, kita dapat menuliskannya sebagai:

4 x 10^0 = 4
3 x 10^1 = 30
2 x 10^2 = 200
1 x 10^3 = 1000

in other words, sum of digits raised to the power if their index.

Jadi, bukan hanya komputer, kami, orang-orang, dihitung dari 0 juga.


0

Indeks array adalah offset dari lokasi memori dasar ke lokasi memori elemen. Elemen i adalah Base + i. Elemen pertama terletak di lokasi Base, jadi di lokasi 0 (Base + 0).


0

Terlepas dari efisiensi komputasi, ada juga aspek lain dalam penghitungan. Ada dua cara untuk memberikan setiap elemen nomor berurutan:

  1. Jumlah elemen sebelumnya (keseluruhan) (nomor kardinal)
  2. Posisi elemen (angka urut)

Usia manusia adalah angka-angka utama: pada tahun pertama setelah kelahiran bayi ia berusia 0 tahun, karena telah hidup selama nol tahun penuh.

Tahun dalam tanggal adalah angka urut: pada tahun pertama Anno Domini (AD), tahun adalah 1 M. Tidak ada tahun 0, sama seperti tidak ada apa pun di nol .

Bahasa pemrograman (seperti Matlab dan Mathematica) di mana indeks elemen mewakili posisinya dalam array mulai menghitung dari 1: elemen pertama . Dalam bahasa lain (seperti semua bahasa berbasis C) indeks elemen adalah jumlah elemen sebelumnya, dan karena itu elemen pertama adalah 0.


Tentu saja, Matteo hanya benar sebagian ketika menyatakan bahwa pengindeksan berbasis nol lebih efisien.

element(n) = address + n * element_size

Pengindeksan berbasis satu bisa sama efisiennya jika semua alamat array sudah ada yang element_sizedikurangi. Ini dapat dilakukan ketika array dialokasikan, dalam hal ini sama cepatnya:

array_address = address - element_size
element(n) = array_address + n * element_size

-1

Komputer secara tradisional menghitung nilai numerik mulai dari nol. Misalnya, array dalam bahasa pemrograman berbasis C mulai dari indeks nol.

0 ... Anda mengacaukan konsep yang berbeda: bahasa pemrograman, komputer dan berhitung.

  1. Menggunakan 2 status (kebanyakan dari mereka secara skematis melakukan hal itu) berarti Anda dapat memilih 2 digit untuk memetakannya (untuk, katakanlah, rujuk). "3" dan "5" (atau "F" dan ",") akan baik-baik saja, tetapi kemudian Anda akan bertanya mengapa komputer dihitung dari "3" (atau dari "F"). Pilihan alami adalah 0 dan 1 jelas.
  2. Array dalam Pascal mulai dari 1. Bahasa itu agak lebih abstrak daripada level rendah C.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.