¿Cómo se realizan operaciones con números grandes usando una ALU pequeña de ancho fijo?

Quiero diseñar una calculadora simple como la que encontrarías en la tienda de dólar. Algo como esto:

Calculadora sencilla

Este pequeño puede mostrar un número de 8 dígitos, lo que significa que 99999999 es el número más grande que se puede mostrar en este formato.

Estoy familiarizado con cómo funciona una ALU simple con dos registros como entrada.

Ahora, si usara un registro de 32 bits para los cálculos, entonces todo estaría bien ya que el registro puede contener 99999999 perfectamente. Sin embargo, quiero entender el proceso de usar dos registros más pequeños para contener números más grandes y cómo funciona eso con una ALU.

¿Quiere que pueda manejar cálculos de punto flotante, o solo de punto fijo, o solo de números enteros?
Largo plazo, coma flotante, pero para esta pregunta solo los números enteros estarían bien. Sé que con puntos decimales y binarios hay un número infinito de unos y ceros que se pueden tener, dependiendo de qué tan preciso quieras ser. Las ALU que admiten decimales no son algo con lo que esté familiarizado todavía.
El término general para un número mayor que su ALU, especialmente uno de longitud variable, es "bignum". Algunos lenguajes de programación implementan esto por ti.
Es como hacer aritmética con lápiz y papel: trabaje en un dígito a la vez y realice un seguimiento de los acarreos/préstamos.
Sí, al igual que con un lápiz y papel. La división puede ponerse fea, pero el resto es bastante sencillo. (Por supuesto, necesita algo de almacenamiento adicional para almacenar los números de tamaño completo, además de los resultados intermedios).

Respuestas (2)

Puede manipular números arbitrariamente amplios utilizando una ALU de ancho finito. Sin embargo, se requieren múltiples operaciones cuando el número es más ancho que la ALU.

Para ilustrar esto, usaré un PIC 18 como ejemplo. Esta arquitectura puede manipular solo números de 8 bits directamente. Para sumar las cantidades de 8 bits VAR1 y VAR2 y poner el resultado en SUMA, se necesitaría un código como este (suponiendo que no se necesita la banca o que el banco ya está configurado correctamente):

         movf var1, w ;lleva VAR1 al acumulador
         addwf var2, w ;agregarle VAR2
         movwf sum ;guarda el resultado

Si en cambio VAR1, VAR2 y SUM fueran variables de 32 bits, el código sería:

         movf var1+0, w ;hacer byte 0 (byte bajo)
         añadir wf var2+0, w
         movwf suma+0
         movf var1+1, w ;hacer byte 1
         agregarwfc var2+1, w
         movwf suma+1
         movf var1+2, w ;hacer byte 2
         agregarwfc var2+2, w
         movwf suma+2
         movf var1+3, w ;hacer byte 3 (byte alto)
         agregarwfc var2+3, w
         movwf suma+3

Cada byte se maneja por separado. Tenga en cuenta el uso de ADDWFC en lugar de ADDWF para todos menos el primer byte. Esta instrucción agrega los dos bytes pero también agrega el acarreo de la operación ALU anterior.

Con suerte, puede ver que este enfoque se puede usar para sumar dos números arbitrariamente grandes. Es posible una aritmética amplia, solo que toma más tiempo y requiere múltiples viajes a través de la ALU para realizar toda la operación.

Las operaciones como AND, OR, XOR, etc., son bit a bit independientes. Cada bit de salida se puede calcular dados solo los bits de entrada correspondientes. Dichas operaciones escalan linealmente con el ancho de los valores que se procesan. La suma requiere los dos bits de entrada, pero también el resultado del acarreo del siguiente bit inferior. Eso requiere que se mantenga un bit de estado entre operaciones sucesivas, pero aún se escala linealmente con el ancho del número.

Multiplique las escalas con el cuadrado del ancho del número, ya que cada parte de un número debe multiplicarse por todas las partes del otro número. Multiplicar dos números de 32 bits, que puede producir un resultado de hasta 64 bits, lleva mucho más tiempo que 8 x 8 en una ALU de 8 bits, pero todo es posible.

Por lo general, haría una calculadora de este tipo con una ALU de 4 bits (un dígito BCD) y haría todos los cálculos en BCD un dígito a la vez, por lo que su registro de almacenamiento sería de 8 dígitos x 4 bits = 32 bits en total.

Incluso con una frecuencia de reloj baja, es más que suficiente para la interacción humana y minimizará el hardware.

Para sumar, simplemente agregue un dígito a la vez, de derecha a izquierda, hasta que haya hecho los 8 (teniendo en cuenta los acarreos). La resta es similar.

La multiplicación y la división son básicamente sumas o restas repetidas y se pueden hacer de manera similar (es posible que tenga que sumar 9 * 9 * 8 veces con una ALU de 4 bits para hacer una multiplicación de 8 dígitos x 8 dígitos; en el peor de los casos, 99999999 * 1, por ejemplo .

El resultado, al estar en BCD, se puede enviar casi directamente a la pantalla LCD (a pesar de la codificación de 7 segmentos y quizás la conducción LCD triplex).

Por supuesto, puede hacer este tipo de cosas más fácilmente en estos días usando una ALU de 32 bits y escribiendo código usando la codificación manual del ensamblador de las matemáticas, dobles en C, etc. pero no es así como funcionan las calculadoras baratas.