¿Por qué las computadoras cuentan desde cero?

55

Las computadoras tradicionalmente registran valores numéricos a partir de cero. Por ejemplo, las matrices en lenguajes de programación basados ​​en C comienzan desde el índice cero.

¿Qué razones históricas existen para esto, y qué ventajas prácticas tiene contar desde cero sobre contar desde uno?

Nota: Esta pregunta requiere respuestas técnicas bien explicadas, no solo opiniones, y está destinada a cubrir las computadoras en general en lugar de solo la programación. Esta pregunta amplía la pregunta de los programadores "¿Por qué las estructuras / matrices están basadas en cero?" .

revs bwDraco
fuente
17
Opinión de Djkstra
Bakuriu
99
Ha habido más de unos pocos ejemplos de lenguajes de computadora que usaron matrices de origen 1.
Daniel R Hicks
23
¿Por qué los humanos no cuentan desde 0?
Sin título
47
Woah, woah, nadie cuenta desde cero, indexamos desde cero. Nadie dice el elemento "zeroth". Decimos el "primer" elemento en el índice 0. Piense en el índice como a qué distancia se desplaza un elemento de la primera posición. Bueno, el primer elemento está en la primera posición, por lo que no está compensado en absoluto, por lo que su índice es 0. El segundo elemento como un elemento antes que él, por lo que está desplazado 1 elemento y está en el índice 1
mowwwalker
14
@Ramhound No, no lo es. La indexación basada en cero no tiene ninguna relación con el uso del binario.
Peter Olson

Respuestas:

88

Contar matrices desde 0 simplifica el cálculo de la dirección de memoria de cada elemento.

Si una matriz se almacena en una posición dada en la memoria (se llama dirección), la posición de cada elemento se puede calcular como

element(n) = address + n * size_of_the_element

Si considera que el primer elemento es el primero, el cálculo se convierte en

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

No es una gran diferencia, pero agrega una resta innecesaria para cada acceso.

Editar

  • El uso del índice de matriz como compensación no es un requisito, sino solo un hábito. El sistema puede ocultar el desplazamiento del primer elemento y tenerlo en cuenta al asignar y hacer referencia al elemento.

  • Dijkstra publicó un artículo "Por qué la numeración debe comenzar en cero" ( pdf ) donde explica por qué comenzar con 0 es una mejor opción. Comenzar en cero permite una mejor representación de los rangos.

Matteo
fuente
8
+1 para la respuesta correcta. Tenga en cuenta que la indexación basada en 0 es solo una convención (muy común) del lenguaje que se utiliza; No es universal. Por ejemplo, Lua usa indexación basada en 1 . La "sustracción innecesaria" puede haber sido el razonamiento detrás de la indexación basada en 0 en los viejos tiempos, pero ahora la mayoría de los lenguajes la usan simplemente porque es a lo que todos ya estamos acostumbrados (en gran parte gracias a C) , y no hay una razón convincente para cambiar eso. convención.
BlueRaja - Danny Pflughoeft 05 de
2
Esto no tiene sentido. La posición de cada elemento siempre se puede calcular address + n * size_of_elementsiempre que la "dirección" sea la dirección del elemento cero. Esto funciona perfectamente si el elemento cero existe como un elemento de la matriz o no. La pregunta es por qué existe el elemento cero, no por qué almacenamos direcciones como la dirección del elemento cero (posiblemente nocional). (Lo cual esto responde.)
David Schwartz
3
@DavidSchwartz Tomemos un lenguaje antiguo como C. Si asigna memoria, obtendrá una dirección donde comienza la memoria. Si un compilador ve algo así v[n], tiene que calcular la dirección de la expresión. Si los índices comienzan con 0, el cálculo es v + x * tamaño. Si en 1 el cálculo es v + (x-1) * tamaño. Por ejemplo, v [1] corresponderá a v + (1-1) * tamaño que es v.
Matteo
44
@David: en C (el lenguaje que realmente popularizó la indexación basada en 0) , las matrices y los punteros son en gran medida intercambiables, por lo que es importante por una serie de razones que en *arrayrealidad se refieren al primer elemento. Un ejemplo: si arrayapuntamos a la ubicación de la memoria antes del primer elemento, la conversión a una matriz de un tipo diferente sería problemática, por ejemplo. la posición del segundo byte en una matriz de ints dependería del tamaño de la palabra; en una máquina de 32 bits, sería a las ((char*)intArray + 5)!!
BlueRaja - Danny Pflughoeft 05 de
3
No, no se trata de si la matriz tiene un elemento cero. Porque, como ves, también hay escala. Si tengo una matriz de objetos de 8 bytes y la superpongo con una matriz de bytes, ¿cuál es el índice de bytes del objeto [42]? Por qué es simple: 42 * 8. El problema con 1 basado es que este desplazamiento de 1 es 1 byte cuando miro la matriz de bytes, y es de 8 bytes cuando miro la matriz superpuesta de 8 bytes.
Kaz
38

Si bien los principios a continuación se aplican al decimal, así como a cualquier otra base, el conteo desde 0 en las computadoras se puede entender fácilmente de forma natural a partir del sistema binario de dígitos fijos que representa los números utilizados en las computadoras. Si tiene 8 bits, existen 256 combinaciones posibles de 1s y 0s que se pueden expresar. Puede usar estos 8 bits para expresar los números 1-256, pero esto dejaría fuera el 0, que es útil en matemáticas como un número en sí mismo, por lo que se usan para expresar los números 0-255.

Esto ya establece un precedente de un orden natural a partir de 0 (todos los 0 en la representación binaria) a 255 (todos los 1 en un número de 8 bits). Considerando el sistema de representación de números, comenzar desde 0 tiene sentido porque 0 es el "primer" número en el sistema, entonces 1 es el "segundo" número, y así sucesivamente.

Una razón adicional por la que comenzar desde 0 en las computadoras es tan conveniente es el concepto de compensaciones. Un desplazamiento es un número que representa la distancia desde una ubicación en la memoria o el disco duro o cualquier otro medio "direccionable". En las computadoras, prácticamente todos los datos se almacenan linealmente, lo que significa que hay un orden en los datos, un primer byte, un segundo byte, etc. Es conveniente expresar la ubicación de "áreas" de datos a través de un desplazamiento. ¿Cuál es el primer byte en un bloque de datos? Está en el desplazamiento '0', lo que significa que se encuentra 0 bytes después del primer byte en el bloque de datos. Si bien es posible que "1" designe el primer byte, esto crea complicaciones en la representación de los datos por varias razones:

  • Al excluir 0 del uso para direccionar datos, reduce la cantidad de cosas que puede abordar con un número de 8 bits en uno.
  • Para calcular el desplazamiento, que es necesario en el nivel de hardware de acceso a datos, en algún momento debe restar uno de la numeración, lo que introduce una complejidad.
  • Los punteros a un bloque de datos siempre apuntan al primer bloque, por lo que la aritmética es sencilla cuando comienza desde 0. (es decir, el primer byte en el primer bloque del primer grupo de datos es 0 + 0 + 0 cuando comienza desde 0 , es 1 + 1 + 1 - 1 -1 cuando comienza desde 1.) La aritmética para esto cuando comienza desde 1 con estructuras de datos anidadas como este ejemplo puede ser confusa.
revs Dougvj
fuente
31
No tiene nada que ver con la representación binaria. Tanto binario y números decimales comienza desde 0.
Matteo
2
Si comienza a contar desde 0, no reduce el número de direcciones que podría (en teoría) pasar de 1 a 257.
Matteo
66
@Matteo no está en un solo byte que no podrías
Deja de dañar a Monica el
8
@Dougvj El conteo basado en cero no tiene absolutamente nada que ver con el binario. El punto que está haciendo es usar cada número en una representación de dígitos fijos, lo cual es una preocupación independientemente de si está utilizando la base 2, la base 10 o la base 23517.
Peter Olson
2
-1 No tiene absolutamente nada que ver con la representación binaria.
BlueRaja - Danny Pflughoeft 05 de
26

Nunca pensé que una oportunidad para un filósofo de sillón como yo vendría en Superuser. Aquí hay una idea errónea fundamental en el fondo, porque los no filósofos tienden a saltear los detalles minuciosos. En resumen: las computadoras no cuentan desde cero, pero la denominación de las posiciones comienza desde cero.

No hay nada confuso sobre esta inconsistencia percibida entre la computadora y las técnicas de conteo humano (cualquiera). Descompongamos la pregunta.

¿Por qué las computadoras cuentan desde cero?

  • No cuentan desde cero

Las computadoras registran valores a partir de cero. Por ejemplo, matrices en C.

  • El índice (indicador de posición, cuenta) comienza desde cero. El recuento de elementos en una matriz donde hay un único elemento en el índice cero es uno

Cero es práctico para representar un vacío de algo o el punto medio de una escala. No es práctico para contar nada porque es imposible por definición de cero.

En el mismo sentido que el punto medio de una escala, el cero se puede usar para representar el borde mismo (comienzo absoluto) de una colección. La pregunta no tiene sentido porque es inconsistente entre los "valores de conteo" y el "conteo desde cero".

Entonces, sí, las computadoras cuentan desde cero, pero cuentan desde uno. Las dos palabras tienen un significado diferente.

tal·ly [tal-ee]

sustantivo

  1. una cuenta o ajuste de cuentas; un registro de débito y crédito, del puntaje de un juego o similar.
  2. cualquier cosa en la que se mantiene un puntaje o cuenta.
  3. Un número o grupo de elementos registrados.

contar [kount]

verbo (usado con objeto)

  1. verificar (las unidades o grupos separados de una colección) uno por uno para determinar el número total; agregar; enumerar: contó sus boletos y descubrió que tenía diez.
  2. contar calcular; calcular.
  3. para enumerar o nombrar los números hasta: Cierra los ojos y cuenta diez.

(dictionary.com)


Dougvj describe adecuadamente las razones prácticas, no tengo nada que agregar allí. Si tan solo pudiéramos tener un profesor de CS (de los años 60) para dar una cuenta histórica ...

Ярослав Рахматуллин
fuente
De hecho, ¿cómo sabes dónde comienza la computadora? Todo lo que sabe es que, cuando lo usa, le dice que comience desde cero.
Daniel R Hicks
Estoy hablando de definiciones de conceptos y lógica aquí, no cómo funcionan las computadoras per se. Sé un poco sobre dónde las computadoras comienzan algo porque he tomado cursos de CS.
Ярослав Рахматуллин
1
Para ser completamente pedante, estás comparando un verbo con un sustantivo. Creo que "contar" y "contar" realmente son sinónimos, y ambos pueden usarse como un verbo o un sustantivo.
Brian
1
@Brian Una observación justa y mi intención es ilustrar (de manera pedante) que la confusión surge de una mala interpretación de los términos. No hay realmente una diferencia entre "el primer elemento" y "el elemento en la posición 0". Ambos son el elemento uno. El primero , no " zeroth ". No hay tal cosa como contar desde cero . La enumeración comienza en uno por definición, mientras que el direccionamiento puede ser a-> 1, b-> 2. c-> 3 o 0-> 1, 1-> 2, 2-> 3. El ejemplo más común de "contar desde cero" se puede encontrar en los libros de matemáticas de la escuela intermedia en forma de {x₀, x₁, x₂}, pero el subíndice es un índice .
1
Es solo que los diseñadores realmente deambularon un poco antes de decidirse por el esquema actual. Lo que parece "obvio" ahora no lo era. Y probablemente se podría haber elegido un esquema algo diferente y ahora parecería más "obvio" que lo que tenemos.
Daniel R Hicks
12

Creo que esto ha sido cubierto antes por el " prof.dr. Edsger W. Dijkstra " - Burroughs Research Fellow en una carta de fecha 11 de agosto de 1982: cf EWD831

Titulado: ¿Por qué la numeración debe comenzar en cero ? "¿Hay razones para preferir una convención a la otra? Sí, hay ..."

Tenga en cuenta también que Dijkstra estuvo en el equipo de diseño de ALGOL 68 a finales de 1968. Algol68 permite matrices de 0, 1 o cualquier número que el programador considere apropiado para el algoritmo. cf ( "The Making of Algol 68" relata "¿Puedes definir matrices triangulares?" alguien (Tony Hoare?) interrumpió. "No solo triangular, sino incluso elíptico", respondió Aad, y mostró cómo.)

Específicamente, en Algol68, cuando las matrices (y matrices) se dividen, obtienen un índice @ 1, por lo que existe un sesgo hacia las matrices [1: ...]. Pero el "1 st " límite inferior se puede mover a empezar por el "0 º " posición especificando "@ 0", por ejemplo vector x [4: 99 @ 2], matriz y [4: 99 @ 1,4: 99 @ 0]. Del mismo modo hay un defecto / sesgo de desde 1 en Do ~ od bucles (a menos que " desde 0" se indica explícitamente), y de 1 para el número entero caso i en ~, ~, ~ ESAC y $ c (~, ~, ~ ) $ cláusulas de elección .

Parece que los comentarios de Dijkstra sobre el Borrador de Informe de marzo de 1968 ( MR93 ) y sus insistencias provocaron lo que podría decirse que es una guerra de llamas anterior al uso : "hay escritos que son adorables aunque no gramaticales, y hay otros escritos que son extremadamente gramaticales, pero son asqueroso. Esto es algo que no puedo explicar a las personas superficiales ". EWD230

El Informe Final Algol 68 (FR) salió el 20 de diciembre de 1968 cuando fue resentido en la Reunión de Munich y luego adoptado por el Grupo de Trabajo. Posteriormente, el informe aprobado por la Asamblea General de la IFIP de la UNESCO para su publicación.

Alrededor del 23 de diciembre (?) 1968 Dijkstra, Duncan, Garwick, Hoare , Randell , Seegmuller, Turski, Woodger y Garwick firmaron el AB31.1.1.1 "Informe de Minorías", página 7 (publicado en 1970).

revs NevilleDNZ
fuente
10

La analogía de la distancia que alguien más mencionó se presta a una ilustración muy práctica:

"¿A qué distancia está tu casa de la estación de servicio más cercana?"

"1 milla".

"¿Vives en la estación de servicio?"

"No, si viviera en la estación de servicio, serían 0 millas"

"¿Por qué estás contando desde cero en lugar de desde uno?"

Otro buen ejemplo serían los cumpleaños: no decimos que alguien tiene un año el día en que nace, decimos que es un año después.

Decimos que los años bisiestos o las elecciones presidenciales de los Estados Unidos son cada cuatro años, aunque si se cuenta desde uno: 2000 , 2001, 2002, 2003, 2004 son cinco años. (Por cierto, los romanos lo arruinaron por un tiempo y tuvieron años bisiestos demasiado juntos)

Mi punto es que "contamos" desde cero todo el tiempo en el mundo real: "Cuántas posiciones después del [inicio de la matriz] es el elemento que desea" simplemente es la pregunta que está respondiendo con un conteo desde cero en muchos programas de computadora. No diría que el primer elemento es una posición después del inicio, ¿verdad? Que es el principio.

Aleatorio832
fuente
1
Sus matemáticas con respecto a las elecciones están apagadas por un año. Su ejemplo contiene 2 años de elección dentro de un lapso de 5 años; la ilustración correcta sería que pasan 4 años de una elección a la siguiente, es decir, 2000 -> 2001 (un período de 1 año), 2001 -> 2002, 2002 -> 2003, 2003 -> 2004.
Jimmy
1
@ Jimmy Ese era mi punto : si las personas "contaran desde uno" en el sentido en que quieren que las computadoras lo hagan , contarían 2000 como uno en lugar de como cero. Esto es, por cierto, cómo lo hicieron los antiguos romanos (y de hecho describiría un ciclo como "2000, 2004, 2008" como un ciclo de cinco años).
Random832
2
Su ejemplo de cumpleaños no es universalmente cierto. Por ejemplo, en Corea del Sur, el primer año de vida se cuenta como uno en lugar de cero .
BennyMcBenBen
6

Como ya han dicho otros, las computadoras no cuentan desde cero .

Algunos idiomas indexan desde 0. La indexación desde 0 tiene dos ventajas principales:

  1. Se convierte en ensamblaje de forma natural porque puede interpretarse como un desplazamiento desde un puntero a la primera posición.

  2. No obtienes rarezas cuando quieres negativos. ¿Cuántos años entre 1BC y 1AD? Ninguna. Porque aunque BC es efectivamente fechas negativas, no hay año cero. Si hubiera habido 0AD, no habría ningún problema aquí. Ves el mismo problema en todas partes en la ciencia donde la gente ha definido ingenuamente el primer elemento en un conjunto como +1.

Jack Aidley
fuente
Sí, y toda la estupidez de esperar hasta 2001 para el nuevo milenio. Esto confundió exactamente a aquellas personas que tampoco "obtienen" matrices basadas en cero cuando incursionan en la programación. :)
Kaz
3
Además, si "1 milla" significa "justo aquí", entonces dado que una milla es 1760 pies, significa que "1760 pies" también significa "justo aquí", ¿verdad? Incorrecto, "1 pie" significa justo aquí, ¡Uy! En esta estupidez basada, "justo aquí" es un pie, una pulgada, un centímetro, etc.
Kaz
1
@kaz donde pies => yardas. 1760 yardas en una milla.
Brad
3

El conteo comienza naturalmente en cero

Aquí está el algoritmo para contar manzanas en una canasta:

count := 0

for each apple in basket
   count := count + 1

Después de la ejecución de lo anterior, countcontiene el número de manzanas. Puede ser cero, porque las cestas pueden estar vacías.

Si no usa su tarjeta de crédito durante todo un mes, ¿recibe una factura de 1 dólar? O 1 centavo?

Cuando reinicia el medidor de viaje en el cuentakilómetros de su automóvil, ¿va a 0001 o 0000?

Las matrices pueden proporcionar múltiples vistas de los mismos datos.

Considere una matriz de estructuras de 32 bits d, cada una compuesta de palabras de 16 bits w. Cada palabra se compone de dos bytes de 8 bits b. Bajo cero indexación, la superposición se ve muy conveniente:

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

El objeto de 32 bits d[1]como en la dirección de la palabra w[2]que se calcula fácilmente multiplicando el índice por 2, que es la relación de los tamaños del objeto de 32 y 16 bits. Además, en el direccionamiento de bytes, lo es b[4].

Esto funciona porque cero es cero, en cada unidad de medida: byte, palabra, palabra doble, etc.

Mire el diagrama anterior: se parece mucho a una regla, donde las conversiones de unidades son intuitivas.

Con una indexación basada, rompe:

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

Ahora no podemos simplemente multiplicar el díndice por 2 para obtener el wíndice, o por 4 para obtener el bíndice. La conversión entre unidades se torna torpe. Por ejemplo, para ir de d[2]a b[4], tenemos que calcular ((2 - 1) * 4) + 1 = 5.

Tenemos que restar ese sesgo molesto 1 en las dunidades, luego escalar en el sistema de coordenadas natural basado en cero y luego volver a agregar el molesto 1 en bunidades. Tenga en cuenta que no es lo mismo 1! Restamos el ancho de una palabra doble, pero luego agregamos un ancho de byte .

La conversión entre diferentes vistas de los datos se convierte en algo así como la conversión de Celsius-Fahrenheit.

Aquellos que dicen que las matrices basadas en uno son fáciles de tratar en el nivel de implementación, porque solo hay una simple resta de 1, se engañan a sí mismos y a usted. Esto es cierto solo si no hacemos cálculos de escala entre los diferentes tipos de datos. Dichos cálculos se realizan en cualquier programa que tenga una visión flexible de los datos (por ejemplo, una matriz multidimensional a la que también se accede como unidimensional) o que manipule el almacenamiento: por ejemplo, un asignador de memoria, un sistema de archivos o una biblioteca de búfer de cuadros de video.

Minimizando Dígitos

En cualquier base, si queremos usar la menor cantidad de dígitos para implementar un rango de valores que es una potencia de la base, debemos comenzar desde cero. Por ejemplo, en la base diez, tres dígitos son suficientes para darnos mil valores distintos de 0 a 999. Si comenzamos desde 1, nos desbordamos en un solo valor y necesitamos cuatro dígitos.

Esto es importante en las computadoras, porque la cantidad de dígitos en binario se traduce en líneas de dirección de hardware. Por ejemplo, un chip ROM con 256 palabras puede direccionarse de 0 a 255, lo que requiere 8 bits: 00000000 a 11111111. Si se direcciona de 1 a 256, se necesitan nueve bits. Tenemos que agregar un derroche de dirección más a la placa de circuito o circuito integrado. Entonces, lo que posiblemente sucedería en la práctica sería que 0 simplemente se llamaría1 en el nivel de API de software para acceder a ese chip. Una solicitud de la palabra 1 en realidad pondría 00000000 en el bus de direcciones de 8 bits. O bien, una solicitud de 1 se traduciría a la dirección 00000001, como se esperaba, pero una solicitud de 256 se correlacionaría con la dirección de 8 bits 00000000 que de otro modo no se utilizaría, en lugar de la dirección de 9 bits 100000000. Ambos de estos errores son realmente soluciones. búsqueda de un problema , y se evitan por completo mediante el uso constante de 0 a 255 en el hardware, en el software y en todas las interfaces de usuario y documentación.

Los desplazamientos basados ​​en uno son fundamentalmente estúpidos

Considere la teoría de la música occidental, por ejemplo. Tenemos escalas diatónicas con siete notas, ¡pero llamamos al espacio que cubren una octava ! La inversión de intervalos sigue la regla de nueve : por ejemplo, la inversión de un tercio es un sexto (restar tres de nueve). Entonces, tres números diferentes están en juego para algo tan simple: siete (notas en una escala), ocho (octava) y nueve (restar de a invertir).

Si siete notas formaran un septave o heptave, y los intervalos estuvieran basados ​​en cero, entonces restaríamos de siete para invertir. Todo basado en siete.

Además, los intervalos se pueden apilar fácilmente. En el sistema actual, si saltamos por un quinto y luego por un cuarto nuevamente, y luego por un tercero, no podemos simplemente agregarlos. El intervalo resultante es dos menos. ¡No es un duodécimo, sino un décimo! En cada etapa, tenemos que restar uno. Subir por un quinto y luego un cuarto no es un noveno, sino solo una octava.

En un sistema de música con un diseño sensato, podríamos agregar intervalos para determinar los saltos resultantes. Una secuencia de notas que comienza y termina en la misma nota tendría una propiedad similar a la ley de voltaje alrededor de un circuito: todos los intervalos se sumarían a cero.

La teoría de la música y la escritura están muy desactualizadas. La mayor parte no ha cambiado desde los días en que la composición se hacía con plumas a la luz de una vela.

Los sistemas basados ​​en uno confunden a las mismas personas que no pueden manejar matrices basadas en cero

Cuando llegó el año 2000, muchas personas estaban confundidas por qué el nuevo milenio no había comenzado. Aquellos que señalaron que no comenzará hasta 2001 fueron considerados como cacahuetes y pandilleros. Después de todo, tienes 20 años cuando cumples 20, ¿verdad? No cuando cumpla 21 años. Si pensaba que el milenio comenzó el 1 de enero de 2000, no tiene derecho a quejarse de matrices basadas en cero en ningún lenguaje de programación. Funcionan exactamente como te gusta. (Pero, sí, los defensores de los desplazamientos y matrices basados ​​en uno son imbéciles y fiesteros. Los siglos deberían comenzar en los años XX00 y milenios en los años X000).

Los calendarios son tontos, pero al menos la hora del día es cero

Cada nuevo minuto en su reloj comienza con: 00 segundos. Cada nueva hora comienza con 00:00 minutos y segundos. Y, al menos en un reloj de 24 horas, el día llega cuando son las doce de la noche y los incrementos de 11:59:59 a 00:00:00.

Por lo tanto, si desea calcular segundos desde la medianoche para un tiempo como 13:53:04, solo tiene que evaluar 13 * 3600 + 53 * 60 + 4. Sin 1adiciones o restas insípidas .

Discurso de clausura sobre MIDI

Bien, ¿qué pasa con los músicos, incluso los supuestamente técnicos?

MIDI! Utiliza numeración basada en cero para programas y canales en la representación real de los mensajes, ¡pero el engranaje lo muestra como 1! Por ejemplo, los programas 0 a 127 se llaman 1 a 128 en la mayoría de los equipos, pero algunos los llaman 0 a 127 o incluso le dan al usuario una opción.

Los programas 71 a 80 se consideran un "banco" de diez. Lo dice justo en mi pedal MIDI, por ejemplo. Los pedales están etiquetados del 1 al 10 y si estoy en el séptimo banco, eligen los programas 71 a 80. Sin embargo, algunos dispositivos o software de computadora muestran los números de programa 1-128 como 0 a 127, o incluso le dan al usuario un ¡elección! Lo que es peor: ¿sistemas basados ​​en uno o caos creado usando tanto uno como cero al mismo tiempo?

Los números de canal MIDI se llaman del 1 al 16, pero están representados por 0 a 15 binarios. Como a pesar de la presentación basada en uno, algunos equipos usan un interruptor de disps para configurar un número de canal y, a menudo, estos interruptores solo usan el código binario basado en cero. Entonces, si desea el canal 3, debe alternarlo a 0010 (binario 2).

Kaz
fuente
1

Si recuerdo correctamente de mi clase de Conceptos del lenguaje de programación ... los idiomas que tienen un índice 0 y otros que tienen un índice 1 tienen que ver con razones históricas. Algol-68, el abuelo de los lenguajes de programación, en realidad estaba indexado en 1, así como Fortran y algunos otros lenguajes de "negocios" como COBOL. Sin embargo, en algunos de estos idiomas, podría especificar explícitamente cuál sería su índice inicial. Hay una tabla interesante de esto aquí .

Básicamente, en los " Ye Olde Days ", los matemáticos, científicos y otros "académicos" solían usar idiomas indexados en 0, mientras que los usuarios de idiomas como COBOL no tenían sentido comenzar a contar en 0, por lo que en esos idiomas tenía más sentido para comenzar en 1 (parecía menos confuso).

Ahora, si su pregunta se refiere a por qué, en cuanto a por qué una computadora ( no un idioma ), naturalmente, comienza a contar desde cero ... bueno, supongo que es inherente al binario: ex: 0000= cero 0001= uno ... y así sucesivamente adelante...

protocolo desconocido
fuente
44
No tiene nada que ver con la representación binaria. Los números binarios y decimales comienzan desde 0 (como muestra en su ejemplo).
Matteo
Bueno, tiene algo más que ver con el binario. Con cuatro bits, de 0000 a 1111, puede direccionar un banco de memoria de 16 palabras. Si lo hace en una base, necesita cinco líneas de dirección para representar 0001 a 10000. O bien, hace lo que, por ejemplo, hace MIDI con los números de canal: 0000 se usa internamente, ¡pero las interfaces de usuario muestran 1! Sin embargo, si el hardware se basara en decimales, sería el mismo problema. Tres dígitos le dan mil direcciones si comienza desde cero, pero si comienza desde 1, necesita cuatro dígitos.
Kaz
1

El número 0 podría denotar varios significados: valor numérico, ordinal, dirección de memoria, etc.

'Índice cero' no significa que los programadores cuenten desde cero. Denota el primer lugar de un bloque de memoria asignado y '0' es la dirección del mismo.

En C, recorrer una matriz podría escribirse de la siguiente manera:

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

Se puede hacer el mismo trabajo en C #:

Object[] arr;

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

Creo que no hay conteo en ambos ejemplos.

9dan
fuente
1

Comenzar en cero es práctico cuando se describe una distancia de algo. Entonces en esta matriz:

[4,9,25,49]

la distancia desde el inicio de la matriz hasta los 25 es 2; debe omitir dos pasos para llegar allí. La distancia a los 4 es cero: no es necesario moverse desde el principio.

Es práctico pensar así al sumar distancias (o índices): avanzo un paso, luego cero pasos, luego dos pasos, ¿dónde estoy? Estoy en el índice 1 + 0 + 2 = 3. Saltando tres pasos, termino en 49 en la matriz de arriba.

Frank de la televisión
fuente
El conteo de pisos en un edificio realmente debería ser de la misma manera (aunque no lo hagamos así en los EE. UU.) El nivel del suelo debe ser cero porque no ha subido ni bajado; Es una posición inicial.
Sin embargo, la planta baja es la primera a la que vienes. Empiezas a contar cuando entras al edificio, en la planta baja, y sumas a medida que subes. Comenzar en cero tiene sentido si considera que "en un edificio" es el estado predeterminado / normal / natural, que es un comentario interesante sobre la sociedad urbana. El cero para el nivel del suelo también tiene mucho sentido si múltiples subniveles son comunes.
1

Recuerda cómo se representan los números en una computadora. Tomemos una bytevariable. 0 se representa como 00000000 1 en binario. 1 es 00000001. 2 es 00000010. Y así sucesivamente.

Tenga en cuenta que el número más bajo que bytepuede almacenar una lata es 0. Si comenzamos los índices de matriz con 1, entonces el sistema sería ineficiente, ya que ahora tenemos una matriz de longitud 255 en lugar de 256. Dado que los números en un programa C se compilan a números binarios ( ints generalmente, unsigned ints en índices de matriz), parece natural usar 0 como índice inicial, ya que es más eficiente.

Además, en C ++, se a[p]despliega en *(a+p*n), donde nestá el tamaño del tipo de datos. En otras palabras, a[p]significa "Dame el elemento en el índice a+n*p". Si pcomenzamos con 1, tendríamos una porción en blanco / sin usar en el índice a.

1. Por supuesto, surge la pregunta obvia "por qué". ¿Por qué no establecer 00000000 en 1? Simple: la suma binaria (realizada por cascadas de unidades sumadoras completas) es fácil en el hardware cuando 00000000 es 0. La suma binaria es una parte integral de todas las operaciones aritméticas. Si haces que represente 1, deberías decirle al compilador que reste 1 de todos los números, o tendrías que cablear los circuitos sumadores para restar uno primero de los sumandos y agregarlo nuevamente a la suma. (tenga en cuenta que no puede restar uno más tarde, ya que el bit de acarreo puede estar involucrado)

Manishearth
fuente
@sec porque eso se vuelve absurdo a nivel de hardware (ver edición)
Manishearth
1

Módulo

Una cosa que las buenas respuestas existentes aún no mencionan: la indexación basada en cero funciona bien junto con las operaciones de módulo, que por lo tanto se pueden combinar para formar una lista cíclica. Piensa por ejemplo en algo como

color = colors[i % colors.length]

lo que podría dar a cada objeto (indexado por i) un color diferente de la lista colors, hasta que se hayan utilizado todos los colores, en cuyo punto comenzaría nuevamente desde el principio. Expresar lo mismo en la indexación basada en uno es bastante torpe:

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

Las operaciones automáticas de módulo impuestas por la aritmética binaria sin signo de tamaño fijo con envoltura son otro ejemplo de por qué esto tiene sentido.

Atiende a ambos

Otra cosa a considerar es el hecho de que es bastante fácil no usar el primer elemento de una matriz basada en cero. (Esto no es foreachválido para iteraciones de estilo y construcciones de lenguaje similares que tratan la matriz como un todo). Muchos programadores, incluido yo mismo, pueden sentirse un poco incómodos sobre el espacio desperdiciado, pero en la mayoría de las situaciones la cantidad es tan pequeña que estas preocupaciones son infundados Por otro lado, si los idiomas están usando indexación basada en uno, entonces no hay forma de simular un elemento en el índice cero sin mucho código. Entonces, dado que en algunas situaciones la indexación basada en cero es mejor que la basada en uno, elegir cero como la base en todas partes es el enfoque más flexible, a diferencia de uno basado en todas partes, y también es más consistente que las posiciones iniciales configurables.

MvG
fuente
0

Los sistemas informáticos usan números naturales (contando desde 0) y números enteros (contando desde 1). Las personas cuentan cosas en números enteros, lo que las hace intuitivas para las listas de numeración, y muchos lenguajes de programación se aprovechan de eso: BASIC, COBOL, Fortran, Lua y Pascal cuentan todos desde 1. Esos idiomas apuntan a nichos como el procesamiento de datos, el análisis numérico, y enseñanza, donde las listas simples e intuitivas son una ventaja.

Los números enteros se vuelven incómodos cuando comienzas a analizar y manipular la estructura de datos, en lugar de simplemente procesar todo en orden. Cuando necesita referirse a secuencias en una fórmula o algoritmo, es más fácil y menos propenso a errores numerarlas desde 0, como hacen los matemáticos: a 0 , a 1 , an , etc. De lo contrario, a menudo debe ajustar por +1 y –1 para obtener los datos correctos, y es fácil equivocarse, creando errores. Por lo tanto, los lenguajes diseñados para informáticos suelen utilizar números naturales: C, Java y Lisp cuentan todos desde 0.

Más allá de los lenguajes de programación, muchos sistemas informáticos numeran cosas desde 0 porque a eso están acostumbrados los informáticos. Además, debido a que la numeración de 1 conduce a tantos errores insidiosos, muchos de nosotros lo evitamos fuera de los elementos de la interfaz diseñados estrictamente para usuarios finales no técnicos.

Bradd Szonye
fuente
Java ... para informáticos. Jajaja
Kaz
0

La respuesta simple es que el primer número no es 1, es 0.

Explicación: La fórmula para calcular un número de varios dígitos en cualquier base es:

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

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

Tomemos el sistema decimal, es al que estamos más acostumbrados.

Mirando el número 1234, podemos escribirlo como:

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.

Entonces, no son solo las computadoras, nosotros, las personas, contamos desde 0 también.

Metáfora
fuente
0

Un índice de matriz es el desplazamiento desde la ubicación de la memoria base a la ubicación de la memoria del elemento. El elemento i es entonces Base + i. El primer elemento está ubicado en la ubicación Base, por lo que está en la ubicación 0 (Base + 0).

Metáfora
fuente
0

Además de la eficiencia computacional, también hay otro aspecto para contar. Hay dos formas de asignar a cada elemento de una secuencia un número secuencial:

  1. El número de elementos anteriores (enteros) (números cardinales)
  2. La posición del elemento (números ordinales)

Las edades de las personas son números cardinales: en el primer año después del nacimiento de un bebé tiene 0 años, porque ha estado vivo durante cero años enteros.

Los años en fechas son números ordinales: en el primer año Anno Domini (AD), el año es 1 AD. No hay año 0, al igual que no hay nada cero .

Los lenguajes de programación (como Matlab y Mathematica) donde el índice de un elemento representa su posición en la matriz comienzan a contar desde 1: el primer elemento. En otros lenguajes (como todos los lenguajes basados ​​en C), el índice de un elemento es el número de elementos anteriores y, por lo tanto, el primer elemento es 0.


Por supuesto, Matteo es solo parcialmente correcto cuando afirma que la indexación basada en cero es más eficiente.

element(n) = address + n * element_size

La indexación basada en uno puede ser igual de eficiente siempre que todas las direcciones de matriz ya tengan una element_sizerestada de ellas. Esto se puede hacer cuando se asigna la matriz, en cuyo caso esto es igual de rápido:

array_address = address - element_size
element(n) = array_address + n * element_size
Virtlink
fuente
-1

Las computadoras tradicionalmente registran valores numéricos a partir de cero. Por ejemplo, las matrices en lenguajes de programación basados ​​en C comienzan desde el índice cero.

0 ... Estás confundiendo diferentes conceptos: lenguajes de programación, computadoras y contando.

  1. El uso de 2 estados (la mayoría de ellos hace exactamente eso esquemáticamente) significa que puede elegir 2 dígitos para asignarlos (para, por ejemplo, referir). "3" y "5" (o "F" y ",") estarían bien, pero luego preguntarías por qué las computadoras cuentan desde "3" (o desde "F"). La elección natural es 0 y 1 obviamente.
  2. Las matrices en Pascal comienzan desde 1. Ese lenguaje es un poco más abstracto que el C de bajo nivel.
poige
fuente