Bilgisayarlar neden sıfırdan sayılıyor?


55

Bilgisayarlar geleneksel olarak taksitli sayısal değerleri sıfırdan başlar. Örneğin, C tabanlı programlama dillerindeki diziler sıfır dizininden başlar.

Bunun için hangi tarihsel nedenler vardır ve sıfırdan saymanın pratik avantajlarından birinden fazla sayma vardır?

Not: Bu soru, sadece görüşler için değil, iyi açıklanmış teknik cevaplar ister ve sadece programlama yerine genel olarak bilgisayarları kapsar. Bu soru Programcıların sorusu üzerine genişler "Neden yapılar / diziler sıfır tabanlı?" .



9
1 kökenli diziler kullanan birkaç bilgisayar dili örneğinden daha fazlası vardır.
Daniel R Hicks

23
Neden insanlar 0'dan sayılmaz?
Untitled

46
Vay canına, vay canına, kimse sıfırdan sayılmaz, biz indeks sıfırdan. Kimse "sıfır" öğesini söylemez. Adresindeki "ilk" öğeyi söylüyoruz indeks 0. Bir elemanın ilk pozisyondan ne kadar uzakta olduğu endeksi düşünün. Peki, ilk eleman birinci konumdadır, bu nedenle ofset değildir, bu yüzden indeksi 0'dır. Bundan önce bir eleman olarak ikinci eleman, yani 1 eleman ofset olur ve indeks 1'de
mowwwalker

14
@Ramhound Hayır, değil. Sıfır tabanlı indekslemenin ikili kullanımla tamamen ilgisi yoktur.
Peter Olson

Yanıtlar:


87

0'dan dizilerin sayılması, her bir öğenin bellek adresinin hesaplanmasını kolaylaştırır.

Bir dizi bellekte belirli bir pozisyonda (adres olarak adlandırılır) saklanırsa, her bir elemanın pozisyonu hesaplanabilir.

element(n) = address + n * size_of_the_element

İlk elemanı ilk düşünürseniz, hesaplama olur

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

Çok büyük bir fark yok, ancak her erişim için gereksiz bir çıkarma ekliyor.

Düzenle

  • Dizi indeksinin ofset olarak kullanılması bir gereklilik değil, sadece bir alışkanlıktır. İlk elemanın ofseti sistem tarafından gizlenebilir ve eleman tahsis edilirken referans alınırken dikkate alınabilir.

  • Dijkstra "Numaralandırma neden sıfırdan başlamalı?" pdf ) 0 ile başlamanın neden daha iyi bir seçim olduğunu açıklıyor. Sıfırdan başlamak, aralıkların daha iyi temsil edilmesini sağlar.


8
Doğru cevap için +1. 0 tabanlı endekslemenin sadece bir (Çok yaygın) kullanılan dilin sözleşmesi; bu evrensel değil. Örneğin, Lua 1 tabanlı endeksleme kullanıyor . "Gereksiz çıkarma", eski günlerde 0 tabanlı endekslemenin ardındaki sebep olabilirdi, fakat şimdi çoğu dil onu basitçe kullanıyor çünkü herkes zaten alışkın olduğu (büyük ölçüde C sayesinde) ve bu sözleşmeyi değiştirmek için zorlayıcı bir sebep yok.
BlueRaja - Danny Pflughoeft

2
Bu anlamsız. Her elemanın pozisyonu her zaman olduğu gibi hesaplanabilir address + n * size_of_element "adres", sıfırıncı öğenin adresi olduğu sürece. Bu, sıfırıncı öğenin dizinin bir öğesi olarak bulunup bulunmadığını mükemmel şekilde işler. Soru, sıfırıncı öğenin neden var olduğu, neden adresleri (muhtemelen nosyonel) sıfırıncı öğenin adresi olarak sakladığımız değil. (Bu cevaplar.)
David Schwartz

3
@DavidSchwartz Hadi alalım eski C dili olarak. Eğer hafıza tahsis ederseniz, hafızanın başladığı bir adres alırsınız. Bir derleyici gibi bir şey görürse v[n] ifadenin adresini hesaplamak zorundadır. Endeksler 0 ile başlarsa hesaplama v + x * boyutudur. 1'de ise hesaplama v + (x-1) * boyutudur. Örneğin, v [1], v + (1-1) * boyutuna tekabül edecektir.
Matteo

4
@Didid: C (0 tabanlı dizinlemeyi gerçekten popülerleştiren dil) , diziler ve işaretçiler büyük ölçüde birbirinin yerine kullanılabilir, bu nedenle *array aslında ilk elemanı ifade eder. Bir örnek: eğer varsa array hafıza yerini göster önce ilk eleman, farklı tipte bir diziye döküm yapmak zahmetli olur, örneğin. ikinci baytın bir dizideki konumu int s, kelime boyutuna bağlı olacaktır; 32 bit bir makinede ((char*)intArray + 5)!!
BlueRaja - Danny Pflughoeft

3
Hayır, bu dizinin sıfırıncı bir öğesinin olup olmadığına dair bir sorun değildir. Çünkü, görüyorsunuz, ölçeklendirme de var. 8 baytlık nesnelerden oluşan bir dizime sahipsem ve bunu bir bayt dizisi ile örtüştüysem, nesnenin bayt dizini [42] nedir? Neden basit: 42 * 8. 1 temelli sorun, bayt dizisine baktığımda 1 olan bu uzaklık 1 bayt, üst üste bindirilmiş 8 baytlık diziye baktığımda 8 bayt.
Kaz

37

Aşağıdaki prensipler ondalık basamağa da uygulanabilir, ancak bilgisayarlarda 0'dan sayma, bilgisayarlarda kullanılan sayıları temsil eden sabit basamaklı ikili sistemden kolayca anlaşılabilir. 8 bitiniz varsa, ifade edilebilen 256 olası 1s ve 0s kombinasyonu vardır. Bu 8-bit'i 1-256 sayılarını ifade etmek için kullanabilirsiniz, ancak bu matematikte kendi başına bir sayı olarak yararlı olan 0'ı dışarıda bırakır, bu yüzden 0-255 sayılarını ifade etmek için kullanılırlar.

Bu zaten 0'dan (ikili gösterimdeki tüm 0'lardan) başlayarak, 255'ten (8 bitlik bir sayıdaki tüm 1'lerden) başlayan bir doğal düzen emsali oluşturuyor. Sayıları temsil etme sistemi göz önüne alındığında, 0'dan başlamak mantıklıdır, çünkü 0 sistemdeki "ilk" sayıdır, yani 1 "ikinci" sayıdır, vb.

Bilgisayarlarda 0'dan başlamanın bu kadar kullanışlı olmasının bir diğer nedeni de ofset konseptidir. Kaydırma, bellekteki veya sabit diskteki bir konumdan veya herhangi bir "adreslenebilir" ortamdan mesafeyi temsil eden bir sayıdır. Bilgisayarlarda, pratik olarak tüm veriler doğrusal olarak depolanır, yani verilere bir düzen vardır, bir ilk bayt, ikinci bayt, vb. Veri bloğundaki ilk bayt nedir? '0' konumunda, yani veri bloğundaki ilk bayttan sonra 0 bayt bulunduğu anlamına gelir. İlk baytı "1" olarak tanımlamak mümkün olsa da, bu, verilerin gösterilmesinde çeşitli nedenlerle komplikasyonlar yaratır:

  • 0'ın verileri ele almak için kullanılmasının dışında tutulduğunda, 8 bitlik bir sayı ile ele alabileceğiniz şey sayısını birer azaltır.
  • Veri erişiminin donanım seviyesinde gerekli olan ofseti hesaplamak için, bir noktada bir karmaşıklığı ortaya çıkaran numaralandırmadan bir tane çıkarmanız gerekir.
  • Veri bloğundaki işaretçiler her zaman ilk bloğa işaret eder, bu nedenle 0'dan başladığınızda aritmetik basittir (yani, ilk veri kümesinin ilk satırındaki 1. bayt 0'dan başladığınızda 0 + 0 + 0 olur. , 1'den başladığınızda 1 + 1 + 1 - 1 -1'dir.) 1'den başladığınızda bunun için aritmetik bu örnekte olduğu gibi iç içe geçmiş veri yapılarını karıştırmak kafa karıştırıcı olabilir.

30
İkili gösterimle ilgisi yoktur. Hem ikili hem de ondalık sayılar 0'dan başlar.
Matteo

2
0'dan saymaya başlarsanız (teoride) yapabileceğiniz adres sayısını azaltmazsınız (1'den 257'ye).
Matteo

6
@Matteo tek bir baytta değil
OrangeDog

8
@Dougvj Sıfır tabanlı sayım kesinlikle var hiçbir şey değil ikili ile yapmak için. Yaptığınız nokta, her bir sayıyı sabit basamaklı gösterimde kullanmakla ilgilidir; bu, taban 2, taban 10 veya taban 23517'yi kullanıp kullanmadığınıza bakılmaksızın endişe vericidir.
Peter Olson

2
-1 İkili gösterimle kesinlikle ilgisi yoktur.
BlueRaja - Danny Pflughoeft

26

Asla benim gibi bir koltuk filozofu için Süper Kullanıcı'nın bir fırsatın olacağını düşünmemiştim. Burada temel bir kavram yanılgısı var, çünkü filozof olmayanlar dakika detaylarını geçme eğilimindedir. Kısacası: Bilgisayarlar sıfırdan sayılmaz, ancak konumların değeri sıfırdan başlar.

Bilgisayar ve insan (herhangi) sayma teknikleri arasında algılanan bu tutarsızlık hakkında kafa karıştırıcı bir şey yoktur. Sorunu çözelim.

Bilgisayarlar neden sıfırdan sayılıyor?

  • Sıfırdan sayılmazlar

Bilgisayarlar sıfırdan başlayan taksitli değerler. Örneğin, C dizileri

  • indeks (pozisyon göstergesi, taksitli) sıfırdan başlar. saymak Sıfır dizinde tek bir öğenin olduğu bir dizideki öğelerin listesi bir

Sıfır, bir şeyin boşluğunu veya ölçeğin orta noktasını temsil etmek için pratiktir. İçin pratik değil sayma bir şey çünkü sıfır tanımıyla imkansız.

Ölçeğin orta noktasıyla aynı anlamda, sıfır, bir koleksiyonun çok kenarını (mutlak başlangıcı) temsil etmek için kullanılabilir. Soru anlamsız çünkü "taksitli değerler" ile "sıfırdan say" arasında tutarsızlık var.

Öyleyse evet, bilgisayarlar sıfırdan hesap yapıyorlar, ancak birinden sayılıyorlar. İki kelime farklı anlam taşır.

sayım yapmak [Tal-ee]

isim

  1. bir hesap veya hesaplaşma; Bir oyunun puanının ya da benzerinin bir borç ve kredi kaydı.
  2. Bir puan veya hesabın tutulduğu herhangi bir şey ..
  3. kaydedilmiş bir öğe veya grup.

saymak [Kount]

fiil (nesne ile birlikte kullanılır)

  1. toplam sayıyı belirlemek için tek tek kontrol etmek (bir koleksiyonun ayrı birimleri veya grupları) tek tek kontrol etmek; ekleme; saymak: Biletlerini saydı ve on tanesini buldu.
  2. hesaba katmak; hesaplamak; hesaplamak.
  3. Sayıları listelemek veya isimlendirmek için: Gözlerini kapat ve on sayı.

dictionary.com


Pratik sebepler Dougvj tarafından yeterince açıklanmış, ekleyecek hiçbir şeyim yok. Keşke tarihi bir hesap verecek bir CS profesörüne (60'lı yaşlardan itibaren) sahip olsaydık ...


Aslında, bilgisayarın nereden başladığını nereden biliyorsunuz? Tek bildiğiniz, onu kullandığınızda, sıfırdan başlamasını söylüyorsunuz.
Daniel R Hicks

Burada bilgisayarların nasıl çalıştığını değil, kavramların ve mantığın tanımlarından söz ediyorum. Bilgisayarların herhangi bir şeyi nereden başlattıkları hakkında biraz bilgim var çünkü CS dersleri aldım.
Ярослав Рахматуллин

1
Tamamen sinsi olmak için, bir fiili bir isim ile karşılaştırıyorsunuz. Bence "taksitli" ve "say" gerçekten eş anlamlıdır ve her ikisi de bir fiil veya isim olarak kullanılabilir.
Brian

1
@Bir adil bir gözlem ve niyetim, karışıklığın terimlerin yanlış yorumlanmasından kaynaklandığını (sersemletici bir şekilde) göstermektir. "1. eleman" ile "0 konumundaki eleman" arasında bir fark yoktur. Her ikisi de bir elementtir. ilk , değil " sıfırıncı "Diye bir şey yoktur. sıfırdan saymak . Numaralandırma başlar bir tanım gereği, adresleme a-1, b-> 2 olabilir. c-> 3 veya 0-1, 1 - 2, 2-> 3. En yaygın "sıfırdan sayma" örneği, ortaokul matematik kitaplarında {x₀, x₁, x₂} biçiminde bulunabilir - ancak indeks .
Ярослав Рахматуллин

1
Sadece, tasarımcılar mevcut şemaya karar vermeden önce epeyce dolaşıyorlardı. Şimdi "bariz" görünen şey değildi. Ve muhtemelen biraz farklı bir şema seçilebildi ve şimdi sahip olduklarımızdan daha "açık" göründü.
Daniel R Hicks

12

Sanırım bu daha önce " Profesör Doktor. Edsger W. Dijkstra "- Burroughs Araştırma Görevlisi, 11 Ağustos 1982 tarihli bir mektupta: c.f. EWD831

başlıklı: Numaralandırma neden sıfırdan başlamalı? . "Bir sözleşmeyi diğerine tercih etmenin nedenleri var mı? Evet, var ...."

Ayrıca Dijkstra'nın bulunduğunu da unutmayın. ALGOL 68 tasarım ekibi 1968'e kadar geç kaldı. Algol68, 0, 1 veya programcının algoritmaya uygun gördüğü herhangi bir sayıdan dizilere izin veriyor. Bakınız: ( "Algol'un Yapılışı 68" “Üçgen dizileri tanımlayabilir misiniz?” diye anlatıyor biri (Tony Hoare?) araya girdi. “Üçgen değil, hatta eliptik” dedi Aad, ve nasıl olduğunu gösterdi. ')

Spesifik olarak, Algol68'de, diziler (& matrisler) dilimlendiğinde bir indeks @ 1 alırlar, bu nedenle [1: ...] dizilerine doğru bir önyargı vardır. Fakat "1 st " alt sınır başlamak için hareket ettirilebilir "0 inci " "@ 0" belirterek pozisyonu, ör. vektör x [4: 992], matris y [4: 99 @ 1,4: 991]. Benzer şekilde bir varsayılan / önyargı var itibaren 1 inç yapmak döngüler (olmadıkça " itibaren 0 "açıkça belirtildi), ve 1 için tamsayı dava ben içinde ~, ~, ~ esac ve $ c (~, ~, ~) $ seçim maddeleri.

Dijkstra'nın Mart 1968 tarihli Taslak Rapor hakkındaki yorumları ( MR93 ) ve ısrarları tartışmasız bir ön-usen olanı kışkırttı alev savaşı : "Her ne kadar programsız olsa da sevilen yazılar var ve son derece gramer, ancak iğrenç başka yazılar da var. Bu, yüzeysel insanlara açıklayamayacağım bir şey." EWD230

Algol 68 Final Raporu (FR) çıktı 20 Aralık 1968 Münih'te toplanıp daha sonra Çalışma Grubu tarafından kabul edildiğinde. Daha sonra UNESCO Genel Kurulu tarafından onaylanan rapor IFIP yayın için.

23 Aralık civarında (?) 1968 Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger ve Garwick imzaladı AB31.1.1.1 "Azınlık Raporu", sayfa 7 (1970 yayınlandı).


10

Başkasının getirdiği mesafe analojisi, çok pratik bir resme kendini verir:

"Eviniz en yakın benzin istasyonundan ne kadar uzakta?"

"1 mil."

"Benzin istasyonunda mı yaşıyorsun?"

"Hayır, benzin istasyonunda yaşıyor olsaydım 0 mil olurdu"

"Neden bir taneden ziyade sıfırdan sayıyorsunuz?"

Bir başka güzel örnek doğum günleri olabilir - birisinin doğdukları gün bir yaşında olduğunu söylemiyoruz, bir yıl sonra olduğunu söylüyoruz.

Birinden sayılsanız bile, artık yılların veya ABD başkanlık seçimlerinin dört yılda bir olduğunu söylüyoruz: 2000 , 2001, 2002, 2003, 2004 beş yıldır. (Bu arada, Romalılar bir süre bu işi mahvetti ve yıllar boyunca birbirine çok yakın sıçradı)

Demek istediğim, gerçek dünyada her zaman sıfırdan "saymak" - "[dizinin başlangıcından sonra kaç tane pozisyon istediğiniz bir sayıdır" sadece sıfırdan saymakla yanıtladığınız soru olur birçok bilgisayar programında. İlk elemanın bir pozisyon olduğunu söyleyemezsin sonra başlangıç, olur mu? O olduğu başlangıç.


1
Seçimlerle ilgili matematiğiniz bir yıllığına kapalı. Örneğiniz 5 yıl içinde 2 seçim yılı içeriyor; doğru örnek, 4 yılın bir seçimden diğerine geçtiği, yani 2000 - & gt; 2001 (1 yıl), 2001 ->; 2002, 2002 - & gt; 2003, 2003 - & gt; 2004.
Jimmy

1
@Jimmy Bu benim puan - insanlar bilgisayarları istedikleri şekilde "birinden sayılırsa" 2000'i sıfır yerine bir olarak sayırlardı. Bu, tesadüfen, eski Romalıların gerçekte nasıl yaptıklarını (ve gerçekten de "2000, 2004, 2008" gibi bir döngüyü beş yıllık bir döngü olarak tarif eder).
Random832

2
Doğum günü örneğiniz evrensel olarak doğru değil. Örneğin, Güney Kore'de yaşamın ilk yılı sıfır yerine bir olarak sayılır. .
BennyMcBenBen

6

Başkaları tarafından zaten söylendiği gibi bilgisayarlar sıfırdan sayılmaz .

Bazı diller 0'dan dizin. 0'dan dizin oluşturmanın iki ana avantajı vardır:

  1. Montaja doğal bir şekilde dönüşür çünkü bir göstericiden ilk konuma bir ofset olarak yorumlanabilir.

  2. Negatif olmak istediğinizde garipleşmezsiniz. 1BC ve 1AD arasında kaç yıl var? Yok. Çünkü BC etkili bir şekilde olumsuz tarihler olsa da, sıfır yıl yoktur. 0AD olsaydı burada herhangi bir sorun olmazdı. Bilimde, insanların ilk öğeyi saf bir şekilde +1 kümesinde tanımladıkları yerde aynı sorunu görüyorsunuz.


Evet, ve yeni binyılın 2001 yılına kadar beklemenin aptallığı. Bu, programlamada cüret ettiklerinde sıfıra dayalı dizileri "almayan" insanların kafasını karıştırıyordu. :)
Kaz

3
Ayrıca, "1 mil" "burada" anlamına gelirse, o zaman bir mil 1760 feet olduğundan, "1760 feet "'in de" tam burada "anlamına gelir, değil mi? Yanlış, "1 ayak" burada demek, ayy! Bu temel salaklıkta, "tam burada" bir ayak, bir inç, bir santimetre, vb.
Kaz

@kaz burada ayaklar = & gt; yard. Bir kilometrede 1760 metre.
Brad

3

Doğal sayma sıfırda başlar

İşte sepetteki elmaları sayma algoritması:

count := 0

for each apple in basket
   count := count + 1

Yukarıdakilerin uygulanmasından sonra, count elma sayısını tutar. Sıfır olabilir, çünkü sepetler boş olabilir.

Kredi kartınızı bir ay boyunca kullanmazsanız, 1 dolarlık bir fatura alıyor musunuz? Veya 1 kuruş?

Aracınızdaki kilometre sayacındaki kilometre sayacını sıfırladığınızda, 0001 mi yoksa 0000 mi olur?

Diziler aynı verinin birden fazla görüntüsünü sağlayabilir

32 bit yapı dizisini göz önünde bulundurun d, her biri 16 bitlik sözcüklerden oluşur. w. Her kelime iki 8 bit bayttan oluşur b. Sıfır endekslemenin altında, kaplama çok uygun görünüyor:

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

32 bit nesne d[1] kelime adresinde olduğu gibi w[2] 32 ile 16 bitlik nesnelerin boyutlarının oranı olan indeksi 2 ile çarparak kolayca hesaplanır. Ayrıca, bayt adreslemede b[4].

Bu işe yarar, çünkü her ölçüm biriminde sıfır sıfırdır: bayt, word, double word ve benzeri.

Yukarıdaki şemaya bakın: birim dönüşümlerin sezgisel olduğu bir cetvel gibi görünüyor.

Bir tane temel indekslemeyle, sonları:

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

Şimdi basitçe çarpılamayız. d almak için 2 ile indeksleyin w dizini almak b indeks. Birimler arasındaki dönüşüm sakar hale gelir. Örneğin gitmek d[2] için b[4]hesaplamak zorundayız ((2 - 1) * 4) + 1 = 5.

Bu sinir bozucu 1 önyargı çıkarmak zorundayız d birimler, daha sonra doğal sıfır tabanlı koordinat sisteminde ölçeklendirme yapın ve ardından sinir bozucu 1'i geri ekleyin. b birimleri. Aynı 1 olmadığını unutmayın! Bir çift kelimelik genişlik çıkarırız, fakat daha sonra bir bayt genişlik ekleriz. .

Verilerin farklı görünümleri arasında dönüştürme yapmak, Celsius-Fahrenheit dönüşümü gibi bir şey haline gelir.

Tek tabanlı dizilerin uygulama düzeyinde başa çıkmanın kolay olduğunu söyleyenler, çünkü sadece 1'in basit bir çıkarması kendilerini ve sizi kandırıyor. Bu, yalnızca farklı veri türleri arasında herhangi bir ölçeklendirme hesaplama yapmazsak geçerlidir. Bu tür hesaplamalar, veriler üzerinde esnek bir görüşe sahip (örneğin tek boyutlu olarak da erişilen çok boyutlu bir dizi) veya depolamayı yöneten herhangi bir programda gerçekleşir: örneğin, bir bellek ayırıcısı, dosya sistemi veya video çerçevesi tampon kütüphanesi.

Rakamları En Aza İndirme

Herhangi bir temelde, tabanın gücü olan bir değer aralığı uygulamak için en az sayıyı kullanmak istiyorsak, sıfırdan başlamalıyız. Örneğin, on tabanda, 0 ila 999 arasında bin farklı değer vermemiz için üç basamak yeterlidir. 1'den başlarsak, sadece bir değerle taşarız ve dört basamağa ihtiyacımız vardır.

Bu, bilgisayarlarda önemlidir, çünkü ikili sayıdaki sayıların sayısı donanım adres satırlarına çevrilir. Örneğin, 256 kelimelik bir ROM yongası, 8 bit: 0 00000000 - 11111111 gerektiren 0 - 255 arasında adreslenebilir. 1 - 256 arasında adreslenirse dokuz bit gerekir. Devre kartına veya entegre devreye israfı bir kez daha israf etmeliyiz. Öyleyse, pratikte yaşanabilecek şey 0 olacaktır denilen Bu yonga erişmek için yazılım API düzeyinde 1. 1 kelimesi için bir istek aslında 8 bitlik adres yoluna 00000000 koyar. Veya, 1 için bir istek beklendiği gibi 00000001 adresine çevrilecektir, ancak 256 için bir talep 9 bitlik adres 100000000 yerine başka kullanılmayan 8 bitlik bir adres olan 00000000 ile eşleşecektir. problem arayışı içinde çözümler ve donanımda, yazılımda ve tüm kullanıcı arayüzlerinde ve dokümantasyonunda sürekli olarak 0 ila 255 kullanılarak tamamen önlenir.

Tek tabanlı yer değiştirmeler temelde aptalca

Örneğin Batı müziği teorisini düşünün. Diyatonik Kantarlarımız Yedi Notlar, ancak kapladıkları alanı diyoruz. oktav ! Aralıkların ters çevrilmesi daha sonra kuralını izler. dokuz : örneğin, üçte birinin tersine çevrilmesi altıncıdır (dokuzu üçe çıkartın). Bu yüzden üç farklı sayı çok basit bir şey için oyunda: yedi (ölçeğe göre notlar), sekiz (oktav) ve dokuz (tersinden çevirerek).

Yedi nota bir septav veya heptav yapılmışsa ve aralıklar sıfır temelli olsaydı, yediden tersine çevirirdik. Her şey yedie dayanıyor.

Ayrıca, aralıklar kolayca istiflenebilir. Şu andaki sistemde, eğer beşte bir sonra tekrar dördüncü, sonra da üçte biri oranında sıçrarsak, bunları ekleyemeyiz. Elde edilen aralık iki daha azdır. Bu on iki değil, aslında onda biri! Her aşamada bir tane çıkarmamız gerekiyor. Beşinci ve dördüncü sırada olmak dokuzuncu değil, sadece bir oktav.

Akıllıca tasarlanmış bir müzik sisteminde, ortaya çıkan sıçramaları belirlemek için sadece aralıklar ekleyebiliriz. Aynı nota başlayan ve biten bir nota dizisi daha sonra bir devre etrafındaki voltaj yasasına benzer bir özelliğe sahip olacaktır: tüm aralıklar sıfıra eklenir.

Müzik teorisi ve yazımı çok eski. Oluşan günlerin bir mum ışığında tüy kalemleriyle yapılmasından bu yana çoğu değişmedi.

Tek tabanlı sistemler, sıfır tabanlı dizileri idare edemeyen aynı insanları karıştırıyor

2000 yılı yuvarlandığında, yeni binyılın neden başlamadığı birçok insanın kafası karıştı. 2001 yılına kadar başlamayacağına işaret edenler, parti kakanı ve cüce olarak kabul edildi. Ne de olsa 20 yaşına girdiğinde 20 yaşına giriyorsun, değil mi? 21 yaşını doldurduğunuzda değil. Eğer binyılın 1 Ocak 2000'de başladığını düşünüyorsanız, herhangi bir programlama dilinde sıfır tabanlı dizilerden şikayet etme hakkınız yoktur. Tam olarak nasıl istersen çalışırlar. (Ancak, evet, tek tabanlı yer değiştirme ve dizilerin savunucuları serseri ve parti kakasıdır. Yüzyıllar XX00 yıldan başlamalı, bin yıl X000 yıldan başlamalıdır.)

Takvimler aptal, ancak günün en az zamanı sıfırdır.

Saatinizdeki her yeni dakika, 00 saniye ile başlar. Her yeni saat 00:00 dakika ve saniye ile başlar. Ve en azından 24 saatlik bir saatte, gece yarısı saldırdığında günler ve 11:59:59 00: 00'a kadar artar.

Böylece, gece yarısından saat 13: 53: 04 gibi bir süre için saniyeyi hesaplamak istiyorsanız, sadece değerlendirmeniz gerekir. 13 * 3600 + 53 * 60 + 4. İnsipid yok 1 toplama veya çıkarma.

MIDI hakkında rant kapanıyor

Tamam, müzisyenler, sözde teknik olanlar bile neyin nesi?

MİDİ! Mesajların asıl kablo gösterimindeki programlar ve kanallar için sıfır tabanlı numaralandırma kullanır, ancak dişli 1 tabanlı görüntüler! Örneğin, 0 ila 127 programları çoğu viteste 1 ila 128 olarak adlandırılır, ancak bazıları onları 0 ila 127 olarak çağırır, hatta kullanıcıya bir seçenek sunar.

71'den 80'e kadar olan programlar, on'luk bir "banka" olarak değerlendirilir. Mesela MIDI pedalımda çok doğru yazıyor. Ayak şalterleri 1 ila 10 arasında etiketlenir ve yedinci sıradaysam, 71 ila 80 arasındaki programları seçerler. Ancak, bazı cihazlar veya bilgisayar yazılımları 1-128 program numaralarını 0 ila 127 olarak gösterir, hatta kullanıcıya bir seçim! Daha kötüsü: tek tabanlı sistemler mi, yoksa aynı anda hem sıfır hem de sıfır kullanılarak yaratılan kaos mu?

MIDI kanal numaraları 1 ila 16 olarak adlandırılır, ancak 0 ila 15 ikili ile temsil edilir. Sanki bir tabanlı sunuma rağmen, bazı donanımlar bir kanal numarasını yapılandırmak için bir diski kullanıyor ve bu anahtarlar genellikle sıfır tabanlı ikili kodu kullanıyor. Bu nedenle, 3. kanalı istiyorsanız, onu 0010'a (ikili 2) geçirmelisiniz.


1

Programlama Dili Kavramları sınıfımdan doğru hatırlıyorsam ... 0 indekslenmiş diller ve 1 indeksli diller geçmiş sebeplerle ilgiliydi. Programlama dillerinin büyükbabası Algol-68 aslında 1 indeksli, Fortran ve COBOL gibi bir kaç "işletme" dili daha vardı. Bununla birlikte, bu dillerin bazılarında, başlangıç ​​dizininizin ne olacağını açıkça belirtebilirsiniz. Bunun ilginç bir tablosu var İşte .

Temelde geri " Siz Olde Günleri "matematikçiler, bilim insanları ve diğer" akademisyenler "genellikle 0 indeksli diller kullanırken, COBOL gibi dillerin kullanıcıları 0'da saymaya başlamanın hiçbir yararı olmadığını, bu nedenle bu dillerde 1'de başlamanın daha anlamlı olduğunu söyledi (daha az görünüyordu) kafa karıştırıcı).

Şimdi sorunuza niçin neden bir bilgisayar ( dil değil ) doğal olarak sıfırdan saymaya başlar ... peki ben ikilide doğal olarak var sanırım: örn: 0000 = sıfır 0001 = bir ... çok daha fazlası ...


4
İkili gösterimle ilgisi yoktur. Hem ikili hem de ondalık sayılar 0'dan başlar (örneğinizde gösterildiği gibi).
Matteo

Bir şey var Başka ikili ile yapmak için. Dört bit, 0000 - 1111 arası, 16 kelimelik bir hafıza bankasını adresleyebilirsiniz. Tek tabanlı yaparsanız, 0001 ila 10000'ü temsil etmek için beş adres satırına ihtiyacınız vardır. Ya da, örneğin, MIDI'nin kanal numaralarıyla yaptığı şeyi yaparsınız: 0000 dahili olarak kullanılır, ancak kullanıcı arayüzleri 1! Donanım ondalık tabanlı olsaydı, aynı sorun olurdu. Sıfırdan başlarsanız üç basamak size bin adres verir, ancak 1'den başlarsanız, dört rakama ihtiyacınız vardır.
Kaz

1

Sayı 0, çeşitli anlamları ifade edebilir: sayısal değer, sıra, hafıza adresi, vs.

'Dizin sıfır', programcıların sıfırdan sayıldığı anlamına gelmez. Tahsis edilmiş bir hafıza bloğunun ilk sırasını belirtir ve '0' adresidir.

C'de, bir dizi boyunca döngü aşağıdaki gibi yazılabilir:

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

Aynı iş C # 'da yapılabilir:

Object[] arr;

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

Her iki örnekte de sayım olmadığını düşünüyorum.


1

Sıfırdan başlamak, bir şeye olan uzaklığı tanımlarken pratiktir. Yani bu dizide:

[4,9,25,49]

dizinin başlangıcından 25'e kadar olan mesafe 2'dir - oraya ulaşmak için iki adımı atlamanız gerekir. 4'e olan mesafe sıfırdır - baştan hiç hareket etmenize gerek yoktur.

Mesafeleri (veya indeksleri) eklerken böyle düşünmek pratiktir - Bir adım, sonra sıfır adım, ardından iki adım, neredeyim? 1 + 0 + 2 = 3 indeksindeyim. Üç adımı atlayarak yukarıdaki dizide 49'a ulaşıyorum.


Bir binadaki kat sayımı gerçekten aynı olmalıdır (ABD'de bu şekilde yapmasak bile) Zemin seviyesi sıfır olmalıdır, çünkü yukarı veya aşağı gitmediniz; bu bir başlangıç ​​pozisyonu.

Oysa giriş katı ilk siz geliyorsunuz. Binaya girdiğinizde zemin katta saymaya başlıyorsunuz ve ilerledikçe ekliyorsunuz. Sıfırdan başlamak, "bir binada", kentsel toplumla ilgili ilginç bir yorum olan varsayılan / normal / doğal durum olduğunu düşünüyorsanız mantıklıdır. Zemin seviyesi için sıfır, eğer birden fazla alt seviye ortaksa, çok anlamlı olur.

1

Bir bilgisayarda sayıların nasıl temsil edildiğini unutmayın. Bir alalım byte değişken. 0 00000000 olarak temsil edilir 1 İkili olarak 1, 00000001'dir. 2, 00000010'dur.

Not: En düşük byte 0 ile dizi indeksini başlattığımızda, sistem verimsiz olur, çünkü artık 256 yerine bir uzunluk 255 dizisine sahibiz. Bir C programındaki sayılar ikili sayıları derler ( int genellikle unsigned int dizi dizinlerinde s), daha verimli olduğu için 0'ı başlangıç ​​dizini olarak kullanmak doğal görünmektedir.

Ayrıca, C ++ 'da, a[p] için açılır *(a+p*n), nerede n veri türünün boyutu. Diğer bir deyişle, a[p] "Dizini bana eleman ver a+n*p ". Eğer p ile başladı 1, o zaman dizinde boş / kullanılmamış bir kısmı olurdu. a.

1. Tabii ki, açık bir soru "neden" ortaya çıkıyor. Neden 00000000'i 1'e ayarlamıyorsunuz? Basit: 00000000 0 olduğunda ikili toplama (tam toplayıcı ünitelerin kaskadları ile yapılır) donanımda kolaydır. İkili ekleme tüm aritmetik işlemlerin ayrılmaz bir parçasıdır. 1'i temsil edecekseniz, derleyiciye tüm numaralardan 1 çıkarmasını söylemeniz gerekir veya toplayıcı devreleri önce eklerden bir tane çıkarmak ve toplamı geri almak için sabit hatlandırmanız gerekir. (taşıma biti olabileceğinden, bir tanesini daha sonra çıkaramayacağınızı unutmayın)


@sec çünkü donanım düzeyinde bu saçma hale gelir (bkz. düzenleme)
Manishearth

1

Modülo

Mevcut iyi cevapların henüz bahsetmediği bir şey var: sıfır tabanlı indeksleme, bu nedenle döngüsel liste oluşturmak için birleştirilebilecek modulo işlemleriyle birlikte iyi çalışır. Örneğin bir şey hakkında düşünün

color = colors[i % colors.length]

hangi her nesneyi verebilir i ) listeden farklı bir renk colors, tüm renkler kullanılıncaya kadar, bu noktada baştan tekrar başlar. Aynı şeyi tek tabanlı endekslemede ifade etmek oldukça sakar:

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

Etrafı saran sabit büyüklükte imzasız ikili aritmetik tarafından uygulanan otomatik modulo işlemleri, bunun neden anlamlı olduğunu gösteren başka bir örnektir.

Her ikisi için de

Dikkate alınması gereken bir diğer şey, oldukça kolay olduğu gerçeğidir. değil sıfır tabanlı bir dizinin ilk öğesini kullanın. (Bu tutmuyor foreach Diziyi bir bütün olarak ele alan stil yinelemesi ve benzer dil yapıları.) Kendim dahil olduğum birçok programcı boşa harcanan alan hakkında biraz garip hissedebilir, ancak çoğu durumda bu endişe duyulmayacak kadar küçüktür. Diğer yandan, eğer diller tek tabanlı bir indeksleme kullanıyorsa, o zaman sıfır kodundaki bir elemanı çok fazla kod olmadan simüle etmenin bir yolu yoktur. Böylece verilen bazı durumlarda sıfır temelli indeksleme, tek temelden daha iyidir, temel olarak sıfırı seçerek her yerde her yerde tek tabanlı olanın aksine, daha esnek bir yaklaşımdır ve aynı zamanda yapılandırılabilir başlangıç ​​konumlarından daha tutarlıdır.


0

Bilgisayar sistemleri hem doğal sayıları (0'dan sayma) hem de tam sayıları (1'den sayma) kullanır. İnsanlar sayıları listelerde sezgisel hale getiren şeyleri sayılarla sayarlar ve birçok programlama dili bundan yararlanır: BASIC, COBOL, Fortran, Lua ve Pascal hepsi 1'den sayılır. Bu diller veri işleme, sayısal analiz gibi nişleri hedefler. ve basit, sezgisel listelerin bir avantaj olduğu yerlerde öğretmek.

Her şeyi sırayla işlemek yerine, verilerin yapısını analiz etmeye ve manipüle etmeye başladığınızda tüm sayılar garipleşir. Bir formül veya algoritmadaki dizilere başvurmanız gerektiğinde, matematikçilerin yaptığı gibi bunları 0'dan numaralandırmak daha kolay ve daha az hatalıdır: a 0 , bir 1 , bir n Aksi takdirde, doğru verilere ulaşmak için sık sık +1 ve –1 değerlerini ayarlamanız gerekir ve yanlış sonuç almak kolaydır. Bu nedenle, bilgisayar bilimcileri için tasarlanan diller genellikle doğal sayılar kullanır: C, Java ve Lisp, hepsi 0'dan sayılır.

Programlama dillerinin ötesinde, birçok bilgisayar sistemi de 0'dan fazla şey saymaktadır, çünkü bilgisayar bilimcilerinin alıştığı şey budur. Ayrıca, 1'den numaralandırma çok sinsi böceğe yol açtığı için, çoğumuz teknik olmayan son kullanıcılar için kesinlikle tasarlanmış arabirim öğelerinin dışında kalıyoruz.


Java ... bilgisayar bilimcileri için. LOL!
Kaz

0

Basit cevap, ilk rakamın 1 olmadığı, 0 olduğu.

Açıklama: Herhangi bir temelde çok basamaklı bir sayı hesaplamak için formül:

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

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

Ondalık sisteme geçelim, en çok alıştığımız sistem bu.

1234 numarasına bakarak şu şekilde yazabiliriz:

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.

Yani, sadece bilgisayarlar değil, biz de insanlar, 0'dan sayıyoruz.


0

Bir dizi indeksi, temel bellek konumundan elemanın bellek konumuna olan uzaklıktır. Öğe i sonra Base + i'dir. İlk eleman Base konumunda, yani 0 konumunda (Base + 0).


0

Hesaplamalı verimliliğin yanı sıra, saymanın başka bir yönü daha var. Her öğeye bir dizilimde sıralı sayı vermenin iki yolu vardır:

  1. Önceki (tüm) elemanların sayısı (kardinal sayılar)
  2. Elemanın konumu (sıralı sayılar)

İnsanların yaşları kardinal sayıdır: bir bebeğin doğumundan sonraki ilk yılda 0 yaşındadır, çünkü sıfır yıllardır hayattadır.

Tarihlerdeki yıllar sıra sayılarıdır: ilk yılda Anno Domini (AD), yıl 1 AD'dir. Yıl 0 yok, tıpkı yok olduğu gibi sıfırıncı şey.

Bir elemanın endeksinin dizideki konumunu temsil ettiği programlama dilleri (Matlab ve Mathematica gibi) 1'den saymaya başlar: ilk öğesi. Diğer dillerde (tüm C tabanlı diller gibi) bir öğenin dizini önceki öğelerin sayısıdır ve bu nedenle ilk eleman 0.


Tabii ki, Matteo sadece kısmen doğru sıfır tabanlı endekslemenin daha verimli olduğunu belirtirken.

element(n) = address + n * element_size

Tek tabanlı bir dizinleme, tüm dizi adreslerinde zaten bir tane olması koşuluyla, etkili olabilir element_size onlardan çıkarıldı. Bu, dizi tahsis edildiğinde yapılabilir, bu durumda bu kadar hızlı olur:

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

-1

Bilgisayarlar geleneksel olarak taksitli sayısal değerleri sıfırdan başlar.   Örneğin, C tabanlı programlama dillerindeki diziler sıfır dizininden başlar.

0… Farklı kavramları karıştırıyorsun: programlama dilleri, bilgisayarlar ve sayım.

  1. 2 durumun kullanılması (çoğu tam olarak bunu şematik olarak yapar), eşlenecek 2 basamağı seçebileceğiniz anlamına gelir (diyelim, bakınız). "3" ve "5" (veya "F" ve ",") iyi olur, ancak o zaman neden bilgisayarların "3" (veya "F" den) saydığını sorarsınız. Doğal seçim açıkça 0 ve 1'dir.
  2. Pascal'daki diziler 1'den başlar. Bu dil, C düzeyinden biraz daha soyut.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.