컴퓨터는 왜 0부터 계산합니까? 실질적인 이점은 1에서 계산하는 것보다 큽니까? 참고 :

컴퓨터는 전통적으로 0부터 시작하여 숫자 값을 집계합니다. 예를 들어 C 기반 프로그래밍 언어의 배열은 인덱스 0에서 시작합니다.

이것에 대한 역사적인 이유는 무엇이며, 0부터 계산하는 것이 실질적인 이점은 1에서 계산하는 것보다 큽니까?

참고 : 이 질문은 단순한 의견이 아니라 잘 설명 된 기술 답변을 요구하며 프로그래밍이 아닌 일반적인 컴퓨터를 다루기위한 것입니다. 이 질문은 프로그래머의 질문 “왜 구조체 / 배열은 0 기반입니까?” .



답변

0부터 배열을 계산하면 각 요소의 메모리 주소 계산이 간단 해집니다.

배열이 메모리의 지정된 위치에 저장되면 (주소라고 함) 각 요소의 위치는 다음과 같이 계산 될 수 있습니다.

element(n) = address + n * size_of_the_element

첫 번째 요소를 첫 번째 요소로 생각하면 계산은

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

큰 차이는 아니지만 각 액세스에 대해 불필요한 빼기를 추가합니다.

편집하다

  • 배열 인덱스를 오프셋으로 사용하는 것은 요구 사항이 아니라 습관입니다. 첫 번째 요소의 오프셋은 시스템에 의해 숨겨지고 요소를 할당하고 참조 할 때 고려 될 수 있습니다.

  • Dijkstra 는 “0으로 시작해야하는 이유”( pdf )를 발간하여 0으로 시작하는 것이 더 나은 선택 인 이유를 설명합니다. 0에서 시작하면 범위를 더 잘 표현할 수 있습니다.


답변

아래의 원칙은 다른 모든 10 진수에도 적용되지만 컴퓨터에서 0부터 계산은 컴퓨터에서 사용되는 숫자를 나타내는 고정 자리 이진 시스템에서 자연스럽게 쉽게 이해할 수 있습니다. 8 비트가있는 경우 표현할 수있는 1과 0의 256 가지 가능한 조합이 있습니다. 이 8 비트를 사용하여 1-256의 숫자를 표현할 수 있지만 0은 수학 자체에서 숫자로 유용한 0을 생략하므로 숫자 0-255를 표현하는 데 사용됩니다.

이것은 이미 0 (2 진 표현의 모든 0)에서 255 (8 비트 숫자의 모든 1)로 시작하는 자연 순서의 선례를 설정합니다. 숫자를 나타내는 시스템을 고려할 때 0은 시스템의 “첫 번째”숫자이므로 1은 “두 번째”숫자이므로 0부터 시작하는 것이 좋습니다.

컴퓨터에서 0부터 시작하는 것이 편리한 이유는 오프셋 개념 때문입니다. 오프셋은 메모리 또는 하드 디스크 또는 다른 “주소 지정 가능”매체의 위치로부터의 거리를 나타내는 숫자입니다. 컴퓨터에서는 실제로 모든 데이터가 선형으로 저장되므로 데이터 순서, 첫 번째 바이트, 두 번째 바이트 등이 있습니다. 오프셋을 통해 데이터의 “영역”의 위치를 ​​표현하는 것이 편리합니다. 데이터 블록의 첫 번째 바이트는 무엇입니까? 오프셋 ‘0’에 있습니다. 즉, 데이터 블록에서 첫 번째 바이트 다음에 0 바이트가 발견됩니다. “1”이 첫 번째 바이트를 지정할 수는 있지만 몇 가지 이유로 인해 데이터를 표현할 때 복잡성이 발생합니다.

  • 데이터 주소 지정에 0을 사용하지 않으면 8 비트 숫자로 지정할 수있는 항목 수가 하나씩 줄어 듭니다.
  • 하드웨어 수준의 데이터 액세스에 필요한 오프셋을 계산하려면 어느 시점에서 번호 매기기에서 하나를 빼야하므로 복잡성이 발생합니다.
  • 데이터 블록에 대한 포인터는 항상 첫 번째 블록을 가리 키므로 0부터 시작할 때 산술이 간단합니다. 즉, 첫 번째 데이터 클러스터의 첫 번째 블록에서 첫 번째 바이트는 0에서 시작하면 0 + 0 + 0입니다. , 1에서 시작할 때 1 + 1 + 1-1 -1입니다.)이 예와 같이 중첩 된 데이터 구조로 1에서 시작할 때의 산술은 혼동 될 수 있습니다.

답변

나와 같은 안락 의자 철학자에게는 수퍼 유저가 등장 할 것이라고 생각하지 않았습니다. 비 철학자들은 세부적인 내용을 건너 뛰는 경향이 있기 때문에 여기에는 근본적인 오해가 있습니다. 한마디로 : 컴퓨터는 0부터 세지 않지만 위치 명칭은 0부터 시작합니다.

컴퓨터와 사람의 계산 기술 사이의 이러한 불일치에 대해 혼동되지 않습니다. 질문을 분해하자.

컴퓨터는 왜 0부터 계산합니까?

  • 그들은 0에서 계산하지 않습니다

컴퓨터 집계 값은 0부터 시작합니다. 예를 들어 C의 배열

  • 인덱스 (위치 표시기 탈리)은 0부터 시작한다. 카운트 단일 요소 인덱스가 배열의 요소들은 제로

영은 무언가의 공극 또는 스케일의 중간 지점을 나타내는 데 실용적입니다. 0을 정의하면 불가능하기 때문에 계산에 실용적이지 않습니다 .

스케일의 중간 점과 같은 의미에서, 0은 컬렉션의 가장 가장자리 (절대 시작)를 나타내는 데 사용될 수 있습니다. 이 질문은 “tally values”와 “count from zero”간에 일치하지 않기 때문에 의미가 없습니다.

예, 컴퓨터는 0부터 집계하지만 1부터 계산합니다. 두 단어는 다른 의미를 지닙니다.

탈리 [tal-ee]

명사

  1. 계정 또는 계산; 직불 및 신용 기록, 게임 점수 등.
  2. 점수 나 계정이 유지되는 모든 것 ..
  3. 기록 된 항목의 수 또는 그룹.

카운트 [쿠트]

동사 (객체와 함께 사용)

  1. 총 수를 결정하기 위해 하나씩 (컬렉션의 개별 단위 또는 그룹) 점검합니다. 합산; 열거 : 그는 티켓을 세고 열 마리를 가지고 있음을 알았습니다.
  2. 생각하기 위해; 계산하다; 계산합니다.
  3. 눈을 감고 10을 세십시오.

(dictionary.com)


실용적인 이유는 Dougvj에 의해 적절하게 설명되어 있습니다. 60 세의 CS 교수에게 역사적인 설명을 해줄 수 있다면 …


답변

나는 이것이 ” prof.dr. Edsger W. Dijkstra ” -1982 년 8 월 11 일자 서한에있는 Burroughs Research Fellow에 의해 다루어 졌다고 생각한다 : cf EWD831

제목 : 번호는 0에서 시작해야하는 이유 . “한 규칙을 다른 규칙보다 선호하는 이유가 있습니까? 네, 있습니다.”

Dijkstra는 1968 년까지 ALGOL 68 설계 팀 에있었습니다 . Algol68은 0, 1 또는 프로그래머가 알고리즘에 적합한 것으로 간주하는 임의의 수의 배열을 허용합니다. cf ( “The Algol 68 만들기” 는 “삼각 배열을 정의 할 수 있습니까?”라고 누군가 (토니 호 아어?)가 중단했습니다.

특히 Algol68에서는 배열 (& 행렬)이 슬라이스 될 때 인덱스 @ 1을 얻으므로 [1 : …] 배열에 대한 편향이 있습니다. 그러나, “1 하한이 시작되도록 이동 될 수있다 “0 매트릭스의 Y [4 : 99 : 99 1,4- @ 예 벡터의 X [2 @ 99 (4)], “@ 0″을 지정하여 위치 @ 0]. 유사의 기본 / 바이어스가 에서 1 할 일이 ~ OD 루프 ( “하지 않는 한 에서 , 그리고 정수 1에서 0″으로 명시되어있다) 경우에서 ~, ~, ~ ESAC C (그리고 $ ~, ~, ~ ) $ 선택 조항.

1968 년 3 월 초안 보고서 ( MR93 ) 에 대한 Dijkstra의 의견 과 그의 주장은 아마도 유즈넷 이전의 화염 전쟁을 일으켰다 . “문법적이지 않더라도 좋아할만한 글이 있고, 매우 문법적이지만 다른 글이있다. 역겨워 요. 이것은 피상적 인 사람들에게 설명 할 수없는 것입니다. ” EWD230

Algol 68 최종 보고서 (FR)는 1968 년 12 월 20 일 뮌헨 회의에서 다시 발표 된 후 실무 그룹에 의해 채택되었습니다. 그 후이 보고서는 유네스코 IFIP 총회에서 승인을 위해 승인되었습니다 .

12 월 23 일 (?) 1968 년 Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger 및 Garwick은 AB31.1.1.1 “소수자 보고서”, 7 페이지 (1970 년 발행)에 서명했습니다 .


답변

다른 사람이 가져온 거리 비유는 매우 실용적인 예를 제시합니다.

“가장 가까운 주유소에서 얼마나 떨어져 있습니까?”

“1 마일”

“주유소에 살아요?”

“아니요, 주유소에 살면 0 마일이됩니다”

“왜 1이 아닌 0에서 세고 있습니까?”

또 다른 좋은 예는 생일입니다. 우리는 누군가가 태어난 날 1 살이라고 말하지 않으며 1 년 후라고 말합니다.

2000 년 , 2001 년, 2002 년, 2003 년, 2004 년 은 5 년 이지만 윤년이나 미국 대통령 선거는 4 년마다 한 번씩이라고합니다 . (우연히도, 로마인들은 이것을 잠시 망쳐 놓았고, 수년이 너무 가까웠습니다)

내 요점은, 우리는 현실 세계에서 항상 0부터 “계산”한다- “[배열의 시작] 이후에 원하는 요소가 얼마나 많은 위치”는 단순히 0에서 카운트로 대답하는 질문 일 뿐이다. 많은 컴퓨터 프로그램에서. 첫 번째 요소가 시작 한 위치라고 말하지 않습니까? 그것은 이다 시작.


답변

다른 사람들이 이미 말했듯이 컴퓨터는 0부터 계산하지 않습니다 .

일부 언어는 0에서 색인화합니다. 0에서 색인화하면 두 가지 주요 이점이 있습니다.

  1. 포인터에서 첫 번째 위치까지의 오프셋으로 해석 될 수 있으므로 자연스러운 방식으로 어셈블리로 변환됩니다.

  2. 네거티브를 원할 때 이상하지 않습니다. 1BC와 1AD 사이에 몇 년이 걸립니까? 없음 BC는 사실상 음수 날짜이지만 연도는 없습니다. 0AD가 있었다면 여기서 아무런 문제가 없을 것입니다. 과학에서 사람들이 첫 번째 요소를 순진하게 +1로 정의한 동일한 문제가 있습니다.


답변

자연스럽게 계산은 0에서 시작합니다

바구니에 사과를 세는 알고리즘은 다음과 같습니다.

count := 0

for each apple in basket
   count := count + 1

위의 실행 후 count사과 수를 보유합니다. 바구니가 비어있을 수 있으므로 0 일 수 있습니다.

한 달 동안 신용 카드를 사용하지 않으면 1 달러의 청구서가 있습니까? 아니면 1 센트?

자동차 주행 거리계에서 트립 미터를 재설정하면 0001 또는 0000으로 이동합니까?

배열은 동일한 데이터에 대한 여러 뷰를 제공 할 수 있습니다

d각각 16 비트 워드로 구성된 32 비트 구조의 배열을 고려하십시오 w. 각 워드는 2 개의 8 비트 바이트로 구성 b됩니다. 제로 인덱싱에서 오버레이는 매우 편리하게 보입니다.

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

32 비트 객체 d[1]워드 주소로서 w[2]용이 32, 16 비트의 객체의 크기의 비율을 2로 인덱스를 곱하여 계산된다. 또한 바이트 주소 지정에서는입니다 b[4].

바이트, 워드, 더블 워드 등 모든 측정 단위에서 0이 0이기 때문에 작동합니다.

위의 다이어그램을보십시오. 단위 변환이 직관적 인 눈금자와 매우 유사합니다.

하나의 기반 인덱싱으로 다음이 깨집니다.

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

이제 d인덱스를 얻기 위해 인덱스에 2를 곱하거나 인덱스를 얻기 위해 w4를 곱할 수 없습니다 b. 단위 간 변환이 어색해집니다. 인스턴스에서 이동의 경우 d[2]b[4], 우리는 계산해야합니다 ((2 - 1) * 4) + 1 = 5.

d단위 에서 성가신 1 바이어스를 빼고 자연 0 기반 좌표계에서 스케일링을 한 다음 성가신 1을 b단위로 다시 추가해야합니다 . 동일하지 않습니다 1! 우리는 하나의 더블 워드 너비를 빼고 1 바이트 너비를 더 합니다.

데이터의 다른 뷰 간 변환은 섭씨-화씨 변환과 유사합니다.

1 기반 배열은 구현 수준에서 다루기가 쉽다고 말하는 사람들은 1을 간단히 빼면 스스로를 속이고 있기 때문입니다. 다른 데이터 유형간에 스케일링 계산을 수행하지 않는 경우에만 해당됩니다. 이러한 계산은 데이터에 대한 유연한 관점 (예 : 1 차원 배열로 액세스되는 다차원 배열)이 있거나 메모리 할당 자, 파일 시스템 또는 비디오 프레임 버퍼 라이브러리와 같은 스토리지를 조작하는 모든 프로그램에서 발생합니다.

자릿수 최소화

어떤 기초에서든, 가장 작은 자릿수를 사용하여 밑의 거듭 제곱 인 값의 범위를 구현하려면 0부터 시작해야합니다. 예를 들어 10 진법에서는 3 자리 숫자만으로도 0에서 999 사이의 천개의 고유 한 값을 얻을 수 있습니다. 1에서 시작하면 하나의 값만 넘치므로 4 자리 숫자가 필요합니다.

이진수의 자릿수가 하드웨어 주소 줄로 변환되므로 컴퓨터에서 중요합니다. 예를 들어 256 워드가 포함 된 ROM 칩은 0에서 255까지 주소 지정할 수 있으며 00000000에서 11111111까지 8 비트가 필요합니다. 1에서 256까지 주소가 지정된 경우 9 비트가 필요합니다. 회로 보드 나 집적 회로에 하나 이상의 주소 추적을 낭비 적으로 추가해야합니다. 실제로 실제로 일어날 수있는 일은 0이 호출 될 것입니다.해당 칩에 액세스하기위한 소프트웨어 API 레벨에서 1입니다. 워드 1에 대한 요청은 실제로 8 비트 주소 버스에 00000000을 넣습니다. 아니면, 일에 대한 요청은 예상대로 00000001를 해결하기 위해 번역,하지만 256에 대한 요청이 달리 사용되지 않는 8 비트 주소 00000000보다는 9 비트 주소 100000000이 가방 물어 뜯는 잡든지 모두를지도 할 것은 정말 의 솔루션 하드웨어, 소프트웨어 및 모든 사용자 인터페이스 및 문서에서 0에서 255까지 일관되게 사용 하면 문제를 검색 할 수 있습니다.

1 기반 변위는 기본적으로 바보입니다

예를 들어 서양 음악 이론을 고려하십시오. 우리는 7 개의 음표로 된 음계 비늘을 가지고 있지만 옥타브 를 덮는 공간이라고 부릅니다 ! 그런 다음 구간의 반전은 9 의 규칙을 따릅니다 . 예를 들어 1/3의 반전은 6 분의 1입니다 (9에서 3을 뺍니다). 따라서 세 가지 숫자 (7 개 (음표 단위), 8 개 (옥타브) 및 9 개 (거꾸로 빼기))가 매우 간단한 것입니다.

7 개의 음표가 9 중음 또는 헵 타브를 만들었고 간격이 0을 기준으로 한 경우 7에서 빼기 위해 거꾸로합니다. 7에 기초한 모든 것.

또한 간격을 쉽게 쌓을 수 있습니다. 현재 시스템에서, 우리가 5 분의 1, 4 분의 1, 3 분의 1로 다시 도약한다면, 우리는 이것들을 추가 할 수 없습니다. 결과 간격이 2 줄어 듭니다. 그것은 열두 번째가 아니라 실제로 열 번째입니다! 각 단계에서 하나를 빼야합니다. 다섯 번째로 올라간 다음 네 번째로 올라가는 것은 아홉 번째가 아니라 한 옥타브입니다.

깔끔하게 설계된 음악 시스템에서는 간격을 추가하여 결과적으로 도약 할 수 있습니다. 동일한 노트에서 시작하고 끝나는 일련의 노트는 회로 주변의 전압 법칙과 유사한 특성을 갖습니다. 모든 간격은 0에 추가됩니다.

음악 이론과 작문은 구식입니다. 촛불의 빛으로 퀼 펜으로 작곡을 한 날부터 대부분의 변화가 없었습니다.

1 기반 시스템은 제로 기반 배열을 처리 할 수없는 사람과 혼동

2000 년이 무너지자 많은 사람들이 왜 새 천년이 시작되지 않은지 혼란 스러웠습니다. 2001 년까지는 시작되지 않을 것이라고 지적한 사람들은 정당 똥꾼과 족제비로 간주되었습니다. 결국, 당신은 20 세가되면 20 대가되었습니다. 밀레니엄이 2000 년 1 월 1 일에 시작되었다고 생각했다면, 어떤 프로그래밍 언어로든 0부터 시작하는 배열에 대해 불평 할 권리가 없습니다. 그들은 당신이 얼마나 좋아하는지 정확히 작동합니다. (그렇지만, 1 기반 변위와 배열의 지지자들은 족집게와 파티 푸퍼입니다. 세기는 XX00 년에 시작해야하며, 천 년은 X000 년에 시작해야합니다.)

캘린더는 멍청하지만 적어도 하루 중 시간은 0을 기준으로합니다.

시계의 새로운 1 분마다 : 00 초로 시작합니다. 각각의 새로운 시간은 00:00 분과 초로 시작합니다. 그리고 적어도 24 시간 제로 자정이되면 낮이 돌아 다니며 11:59:59는 00:00:00으로 증가합니다.

따라서 13:53:04와 같은 시간 동안 자정부터 초를 계산하려면을 평가하면됩니다 13 * 3600 + 53 * 60 + 4. 어리석은 1덧셈이나 뺄셈이 없습니다.

MIDI에 대한 닫는 소리

좋아, 아마도 음악가들, 아마도 기술적 인 사람들은 무엇입니까?

미디! 메시지의 실제 와이어 표현에서 프로그램과 채널에 0부터 시작하는 번호 매기기를 사용하지만 gear는 1부터 시작하는 것으로 표시합니다! 예를 들어 프로그램 0에서 127까지는 대부분의 기어에서 1에서 128까지 호출되지만 일부는 0에서 127까지 호출하거나 사용자에게 선택을 제공합니다.

프로그램 71부터 80까지는 “은행”으로 간주됩니다. 예를 들어 MIDI 페달에 바로 표시됩니다. 풋 스위치는 1에서 10까지 레이블이 붙어 있으며 7 번째 뱅크에있는 경우 프로그램 71에서 80을 선택합니다. 그러나 일부 장치 또는 컴퓨터 소프트웨어는 1-128 프로그램 번호를 0에서 127로 표시하거나 사용자에게 선택! 더 나쁜 점은 1 기반 시스템 또는 1과 0을 동시에 사용하여 만든 혼란입니까?

MIDI 채널 번호는 1 ~ 16이지만 0 ~ 15 이진수로 표시됩니다. 1 기반 프레젠테이션에도 불구하고 일부 기어는 채널 번호 구성을 위해 dispswitch를 사용하며 종종 스위치는 0 기반 이진 코드를 사용합니다. 따라서 채널 3을 원하면 0010 (이진 2)으로 전환해야합니다.