¿Cómo saben los ordenadores qué hacer con el «1» y el «0»? Cada vez que trato de averiguar, es sólo la gente explicando binario, nunca diciendo cómo una computadora sabe, por ejemplo, para tomar ‘0110’ y convertirlo en ‘6’.

No está claro cuál es tu pregunta, pero intentaré responderla de varias maneras. Al principio voy a ser sencillo y debajo de la línea de guiones lo haré más pedantemente correcto.

1) ¿Por qué te explican el binario, cuando tú haces la pregunta? Te explican el binario porque dentro del ordenador hay circuitos que hacen aritmética de complemento a 2s. La aritmética de complemento 2s es «binaria». El ordenador tiene circuitos que saben hacer aritmética binaria. Cuando el programador le dice al ordenador que sume, el ordenador utiliza el circuito que hace la suma del complemento 2s (es decir, binario). En binario de complemento 2s, la cadena de bits 0110 es 6 en aritmética decimal. Por lo tanto, cuando el ordenador calcula está haciendo aritmética binaria. Ver debajo de la línea para otras formas en que el ordenador puede calcular.

2) Ok, ahora supongamos que tenemos 0110 almacenado en algún lugar en el ordenador y queremos que se muestre en la pantalla. ¿Cómo lo hace el ordenador? Esto es mucho más complicado. Tan complicado que, aunque conozco todos los principios de su funcionamiento y he diseñado ordenadores y chips de ordenador y grandes y complejas piezas de software, no conozco todos los detalles relevantes para tu ordenador concreto, así que sólo puedo explicarlo de forma general. Así que, empecemos con lo que el programador escribe. Aquí hay un programa vagamente parecido a C, despojado de detalles irrelevantes, pero hecho para ilustrar tu pregunta. This is called pseudocode by the way.

  1. main () { 
  2. binary integer b = 0110; // b has 0110 in it now 
  3. printf(«%d», b); // print those bits as a decimal number 

Así, en este programa el programador le ha dicho al ordenador que almacene el bit 0110 en algún lugar de su memoria y que llame a ese lugar «b». La siguiente línea le dice al ordenador que queremos imprimir en la pantalla cualquier bit que esté en el lugar llamado «b» pero traduciéndolo a un número decimal.

Ahora, qué es lo importante de esto. El programador le dijo al ordenador que «entendiera» los bits como un número decimal. El programador podría haber utilizado una declaración diferente para hacer que el ordenador los emitiera simplemente como puntos en la pantalla. O tal vez como una letra del alfabeto (que es la 6ª letra del alfabeto, es la «f» en inglés, aunque los ordenadores no saben inglés per se. See below the line for the alphabets the computer does know.

  1. main () { 
  2. binary integer b = 0110; // b has 0110 in it now 
  3. gui.printsprite(b, 0, 5); // print those bits as dots on the screen 

Este programa imprimiría algo más como:

Salvo que los puntos llenarían los espacios que ocupan (y parecerían tocarse). Los puntos añadidos (llamados píxeles) suelen ser bastante pequeños. Ver debajo de la línea para más información sobre eso.

3) Ok, ahora sabemos que el ordenador no sabe lo que es 0110 hasta que el programador le dice cómo interpretarlo. Y el programador utiliza un lenguaje de programación para hacerlo. Y, a continuación, descubriremos que el ordenador no entiende en absoluto los lenguajes de programación. El ordenador sólo entiende su propio lenguaje llamado «código máquina». Ahora bien, el tipo de ordenador determina qué lenguaje de código máquina entiende. Tu PC entenderá el código máquina x86. Tu teléfono (que en realidad es un ordenador) entenderá el código máquina ARM. Los grandes servidores de los bancos suelen entender el código máquina 370. Adivina qué… más en el below the line.

Y el código máquina es sólo patrones de bits como donde 0110 0011 1011 0110 0000 0010 tiene un significado específico para los ordenadores de la misma familia (que entienden el mismo código máquina). No tengo ni idea de lo que significa esa secuencia de bits, pero podría buscarla (o preguntar a alguien como Joe Zbiciak, que se ocupa del código máquina con más frecuencia que yo) lo que significa en algún procesador específico. Tenga en cuenta que el 0110 en el patrón probablemente no significa 6.

Pero de todos modos, tenemos que conseguir que nuestro programa se traduzca en la secuencia apropiada de patrones de bits. Para que le hayamos dicho al ordenador que queremos un 6 impreso en la pantalla (o los puntos o la letra f, etc). Aquí es donde entro yo. Escribo programas especializados llamados compiladores. Son programas que sí «entienden» los lenguajes de programación y qué secuencias de bits hacen que el ordenador haga varias cosas y pueden traducir el lenguaje de programación en el conjunto correcto de bits, para que el ordenador entienda lo que queremos que haga.

4) Hablemos ahora un poco de cómo lo hace el ordenador. El ordenador, en cierto modo, es como un gigantesco reloj mecánico, como las torres de reloj de los ayuntamientos alemanes, con todas las figuritas. Hay el equivalente a engranajes y poleas que ejecutan una danza finamente orquestada. La diferencia clave es que los únicos objetos importantes que se mueven son los electrones. Y, la coreografía de la danza es el programa que el programador escribe después de haber sido traducido a código máquina. Y, si el programador escribe algo mal y dos de las figuritas chocan entre sí, el ordenador sigue los pasos que el programador ha escrito y choca las figuritas entre sí. Hacer lo incorrecto en programación se llama eufemísticamente un «bug» (o si eres un programador sarcástico una «feature» que es un bug con gafas de sol listo para la playa).

Así que, cuando un hacker ha inyectado algún código malo en tu ordenador, éste le envía fielmente el contenido que ha escrito sin importarle que sea la contraseña de tu cuenta bancaria. El ordenador es sólo un reloj mecánico que hace lo que se le ordena y no tiene ni idea de quién fue el programador que creó el código (y no le importa en ningún caso). Simplemente hace lo que se le dice.

5) Pero, de nuevo, demos un paso atrás. Entonces, el ordenador está ejecutando «mecánicamente» unos pasos que de alguna manera hacen que aparezca un 6 en su pantalla. ¿Cómo? Bueno, en primer lugar, el ordenador tiene memoria (RAM) donde guarda cosas. El 0110 está almacenado allí en alguna parte. El ordenador también tiene conexiones que le permiten enviar esos bits a otros lugares, el disco, la pantalla, Internet. Esas cosas se llaman dispositivos. También puede leer de los dispositivos (por ejemplo, el disco, internet, tu teclado). Así que, a este nivel, el ordenador envía el contenido de esa ubicación de la RAM a tu pantalla y le dice que la muestre.

6) ¡Ah, pero hay detalles importantes! Cada dispositivo tiene su propio lenguaje llamado «protocolo». Así es como el dispositivo sabe lo que tiene que hacer. El ordenador cuando habla con el dispositivo tiene que «hablar» ese lenguaje. Hay programas en el ordenador que le dicen cómo enviar información al dispositivo y qué protocolo debe «hablar» para hacerlo. Esos programas se llaman controladores de dispositivos. De nuevo, el ordenador en sí no entiende el protocolo, es el programa[mer] el que lo hace, el ordenador sólo sigue los pasos mecánicos que están codificados en ese programa.

7) Así que, vamos a pasar por lo que realmente sucede. Al ordenador se le dice que «ejecute» el programa y así sigue los pasos del programa. Ahora, cuando llega a la declaración printf, el compilador ha traducido eso en una llamada a una «rutina de biblioteca en tiempo de ejecución» otro conjunto de programas que vienen junto con el compilador y manejan cosas complejas de hacer.

Los programas de la biblioteca ven el %d y conoce los medios para traducir el patrón de bits en un número decimal. Como es un solo dígito, simplemente busca ese dígito en una tabla y ve que la letra «6» en su alfabeto es la opción correcta para ese dígito. Así que pone la letra «6» en su lista de cosas para enviar a la pantalla. Si hay más dígitos, repite el proceso hasta que todos los dígitos estén en esa lista (llamada «buffer»). Ahora, cuando el buffer está lleno o el programa termina, el programa de la librería envía todos los caracteres en el buffer al SO donde lo enviará a la pantalla. Ahora, los caracteres son simplemente patrones de bits que representan el alfabeto de los ordenadores. El carácter para «6» es probablemente el patrón de bits 0011 0110.

El SO entonces busca qué controlador de dispositivo necesita esa cadena de bits y envía la secuencia de bits al controlador de dispositivo que utiliza el protocolo para enviar los bits al dispositivo (la pantalla).

8) Ahora, en algún lugar de ese camino, el patrón de bits para el carácter 6, se tradujo en píxeles. Puede ocurrir cerca de la pantalla y enviar los caracteres a ese hardware o puede ocurrir dentro del ordenador. Wherever it happens 0011 0110 gets turned into a set of pixels—a bit pattern that looks something like this:

  1. 0000000  
  2. 0001100 .. 
  3. 0010000 . 
  4. 0111100 …. 
  5. 0100010 . . 
  6. 0100010 . . 
  7. 0011100 … 
  8. 0000000 

You can see why I don’t design fonts for a living…..

Now, this is a very simplified version of what happens. La mayoría de estos puntos tienen detalles que la gente obtiene títulos y experiencia laboral antes de entender. Y, ni siquiera toqué los aspectos de ingeniería eléctrica o física. Así que, no esperes entender realmente de una pregunta de Quora como esta.

Sé que prometí detalles. Sin embargo, parte de lo que quería escribir se ha evaporado de mi memoria. Puede que amplíe esta respuesta si la gente me recuerda detalles importantes que he pasado por alto y son numerosos.

  1. El complemento a 2s es la forma normal en que la mayoría de los ordenadores modernos manejan la aritmética de «enteros». Sin embargo, en los años 60 el complemento 1s era popular. Y, todavía se encuentran vestigios de ella en IEEE-punto flotante. También existe la aritmética BCD, la aritmética de magnitud con signo, y toda una variedad de otras cosas.
  2. La mayoría de los ordenadores de hoy en día utilizan ASCII o Unicode como alfabeto. ASCII es un superconjunto del alfabeto inglés, con también dígitos, signos de puntuación y un conjunto de «caracteres de control» que hacían cosas útiles cuando usábamos teletipos. Unicode tiene ASCII como subconjunto, pero puede representar la mayoría de los caracteres utilizados en el mundo y una variedad de codificaciones diferentes, en tamaños de 8, 16 y 32 bits (¿y quizás 24 bits?). UTF-8 es esencialmente ASCII con una válvula de escape para obtener caracteres no latinos-1 (es decir, ASCII).

    Píxeles – las celdas de imagen son en realidad lo que su pantalla consiste, pequeños puntos de color. La misma idea se utiliza en las pantallas de televisión y la impresión y un montón de otros lugares. Las bibliotecas de gráficos y los marcos de trabajo de gráficos te permiten dibujar directamente los píxeles y los «sprites» son un término para un conjunto de píxeles que puedes dibujar juntos y tal vez mover en la pantalla. Ten en cuenta que algunos formatos, como los que sirven para dibujar pequeños iconos (.BGP?) son esencialmente formatos de píxeles, pero los formatos de píxeles no son la única forma de especificar imágenes.

    Los gráficos de ordenador son muy complejos y no voy a pretender entender más que lo mínimo al respecto.

  3. Debido a que los patrones de bits de los ordenadores modernos no están diseñados específicamente para ser legibles por el ser humano, sino para empaquetar la información más útil en el menor número de bits y al mismo tiempo ser fáciles de interpretar por el «decodificador» del ordenador en acciones reales, la gente no suele escribir el lenguaje de la máquina, no a mano. La mayoría de la gente utiliza un lenguaje de «alto nivel» y hay literalmente cientos de ellos (especialmente si se incluyen todos los dialectos). Sin embargo, cuando se necesita un control preciso, especialmente de las características que no tienen análogo en un lenguaje de alto nivel, algunos compiladores permiten «escapar» al lenguaje ensamblador, que suele ser una traducción legible para el ser humano, pero trivial, al lenguaje de la máquina.

    En cualquier caso, hay muchas, muchas familias de lenguaje de la máquina. En un momento dado, probablemente podría escribir lenguajes ensambladores para una o dos docenas de familias diferentes. Estoy bastante seguro de que quería enumerar un montón de lenguajes ensambladores representativos, pero no se me ocurre por dónde empezar.

    Y escribir un compilador es definitivamente todo un tema en sí mismo. Tengo varios posts de la misma longitud que este que cubren temas en ese campo.

  4. El hecho de que un ordenador haga exactamente lo que le dices que haga y no lo que quieres que haga es probablemente uno de los aspectos más incomprendidos. Además, los ordenadores no son mágicos. En realidad, son fundamentalmente simples. Sólo capas sobre capas de simplicidad que terminan haciéndolos parecer complejos y ciertamente los hace buggy, ya que casi ninguna de esas capas es perfecta y ciertamente no es perfectamente regular, por lo que hay numerosas sorpresas al acecho para los descuidados y, tristemente, hay muchos, muchos programadores descuidados.

    La seguridad informática y los hackers/hacking es también su propio campo.

  5. Esto es lo más cerca que llegamos a los aspectos de EE (ingeniería eléctrica). Pero hay todo un catálogo de términos que uno puede aprender para entender estas diferentes partes. RAM, ROM, flip flops, registros, RAM estática v. dinámica, PROM, discos duros, disquetes, SSDs, NVME, m.2, 3.5″, 2.5″, SCSI, ATE, NAS, thumb-drives, USB, RJ45, …. y ni siquiera he arañado la superficie.
  6. Los drivers y protocolos de los dispositivos son todo un tema en sí mismos. Creo que escribí uno, una vez. Hay clases enteras en protocolos de red.
  7. Escribir una biblioteca de tiempo de ejecución o un marco de aplicación es una tarea importante. A nivel profesional, suele haber un equipo responsable de ello. Lo mismo ocurre con un sistema operativo.