Puede hacerlo como en tercer grado, como si todos aprendieran a sumar y restar si está trabajando con cadenas basadas en ASCII, lo cual es fácil. ¿O puede hacerlo como aprendí a calcular en mi segundo, o fue el primer grado ?: mediante cálculo binario.
Sí, así aprendí los números. Lo primero fue la teoría de conjuntos, luego aprendimos a contar y agregar binario, terciario y subimos los sistemas de números a 16, luego 60 y luego volvimos a la base diez y trabajamos con eso desde ese momento en adelante.
Mi maestra era muy inteligente, era pelirroja y muy muy grande. Y ella me enseñó los conceptos básicos de las cosas a la edad de seis o siete años que otros no suelen aprender antes de ingresar a la universidad. Eran los años 70 y todo fue revolución. Entonces nací en esto. Y cuento diferente de otras personas, los números tienen un significado diferente para mí.
Pero comencemos con “tercer grado” (¡¿tan tarde ?! wtf). Teníamos un conocimiento completo sobre la sexualidad a esa edad, porque eso era algo que aprendimos también en segundo grado, bueno, una segunda vez en cuarto, quinto, séptimo y genética en décimo más o menos.
Pero volvamos a los números. Sumas dos números sumando los últimos cifrados y sigues con el carry. 8 + 9 = 17, entonces es 7 y se pasa a la siguiente columna. Si solo vuelvo a la primera lección en números que tuve, es binario 1 + 1 = 10 significa 0 y carry. Agrega el carry a la siguiente columna. Nunca puede haber más de un transporte independiente del sistema de números que está utilizando.
Entonces hexadecimal E + F es 1D significa D y carry. No puede estar más allá de F + F = 1E. En decimal no puede ser más de 9 + 9 = 18 en binario no más de 1 + 1 = 10. Siempre obtienes una carga.
Entonces, si está utilizando para agregar sus números en columnas decimales, solo procesa un poco menos de 4 bits a la vez. “Un poco menos” significa definitivamente más de 3 bits, lo que representa 0–7 en el sistema octal y cuatro bits 0-F en hexadecimal. Es exactamente [matemática] 1 / log (2) = 3.32… [/ matemática] dígitos binarios para ser precisos.
Pero nuestros procesadores modernos tienen 64 bits. Entonces eso sería altamente ineficiente.
; dos números para agregar en RDI, RSI
; resultar en RAX (bajo) RDX (alto)
globl add_longc
texto de la sección
add_longc:
xor rdx, rdx; borrar RDX = 0
mov rax, rdi; establecer RAX = RDI
agregar rax, rsi; RAX + = RSI
adc rdx, # 0; RDX + = TRANSPORTAR
jubilado
Esta es la base de suma 2 ^ 64. Interesante es ADD, además sin carry y ADC, además con carry. La bandera de acarreo se establece mediante la primera adición si la suma es mayor de lo que cabe en 64 bits.
No tienes el carry como una construcción en ningún lenguaje de alto nivel. Lo cual es realmente una pena, porque esto es realmente algo sensato. Si intenta hacer esto en C, por ejemplo, tendrá muchos problemas para verificar si hay un carry o no. En ensamblaje son solo dos comandos.
Y como siempre trato de presentar la solución más simple a un problema, esto es: hacerlo en Asamblea. Por supuesto, puede cambiar esta variante simple dando los punteros de memoria del algoritmo a los dos operandos y uno a una matriz de destino y un contador sobre la longitud de esas matrices.
Entonces tendrás números largos arbitrarios y la implementación es definitivamente más rápida que la de BigInt. ¿Qué se hace en C. WTF? Desperdicio de ciclos. Tenemos una máquina haciendo esto. Es como conducir una motocicleta al tener seis tipos musculosos que lo llevan en su bicicleta.
HLL no están hechos para esto. No deben ser utilizados para esto. Quien hace esto en HLL debería haber estado en un campo diferente de la ciencia o al menos dejar de enseñar a los niños.
Este es un problema claro del lenguaje ensamblador. Por cierto, llamas esto desde C por:
extern unsigned long * add_longc (registrar unsigned long a asm (“rdi”), registrar unsigned long b asm (“rsi”));
Pero debido a que estoy en conformidad con la API de 64 bits aquí, esta parte asm (…) no es realmente necesaria, además del “registro” enérgico. Y, por supuesto, no he devuelto el valor de retorno correctamente, lo que debe hacerse a una matriz o estructura de datos en este contexto, pero quería mantener el ejemplo fácil y no resolver su tarea.
Simplemente: no hagas eso en HLL. Nunca lo hagas en HLL. Y tome un palo y golpee a cualquiera que vea haciendo esto en HLL. Este es un problema de lenguaje ensamblador. Todos los HLL descalifican para tratarlo, incluso acercándose a él.
Un lenguaje que no comprende algo como un carry no debe usarse para un problema como este. Y no hay orgullo en hacer que los seis hombres musculosos lleven su motocicleta y griten “¡más rápido!”.