Programación General > Pascal

 SUMAR NATURALES DE HASTA 100 DIGITOS

(1/1)

blaise_pablitus:
:hola: Queridos colegas  "Pascaleros", quisiera compartir con uds. el código de un programa que estuve escribiendo: es un programa que permite sumar dos numeros naturales de hasta cien dígitos (recordemos que el entero mas grande que se puede representar directamente es 65536, o algo así), bueno, aquí va la letra del ejercicio y el código que escribí:

" Se desea trabajar con una aritmética de Naturales de hasta 100 dígitos. Los enteros de Pascal no soportan dicha aritmética, por lo que se piensa utilizar la siguiente representación de Naturales basada en arreglos con tope:

CONST
        MaxDig = 100;
TYPE
     Digito = 0..9;
     Natural = RECORD
                             digitos : ARRAY [1..MaxDig] OF Digito;
                             tope : 0..MaxDig;
                   END;

Escribir un programa que lleve a cabo la suma de naturales en terminos de la estructura anterior.


--- Código: Pascal ---(* Programa que permite sumar numeros naturales de hasta cien dígitos de longitud *)(* utilizando un array con tope *) PROGRAM Aritnat(input,output); CONST    MaxDig = 100;  (* Constante que indica longitud maxima del numero *) TYPE   Digito = 0..9;  (* en cada celda del array se introducirán digitos del cero al nueve *)   Natural = RECORD                  digitos: ARRAY [1..MaxDig] OF Digito;                  tope: 0..MaxDig;             END;VAR  a, b, c:Natural;   (* a y b son los sumandos, c es el resultado de la suma *)  suma, acarreo, i, digit:integer;  (* Variables para procesar los datos *)  temp:integer;  BEGIN     (* Lectura de los números a sumar *)    writeln('Ingrese el primer numero:');        readln(digit); (* Se ingresa el primer digito *)    a.tope := 0;   (* Se inicializa el tope *)    WHILE (digit IN [0..9]) AND ((a.tope < MaxDig) OR (a.tope = MaxDig)) DO         BEGIN   (* Mientras el digito que se ingrese pertenesca al subrango 0..9 y mientras no se haya terminado el array *)             a.tope := a.tope + 1;     (* Se incrementa en uno el tope del array *)             a.digitos[a.tope] := digit;  (* Se almacena el digito en la celda correspondiente *)             readln(digit)             (* Se lee el siguiente digito *)         END;      (* se solicita ingresar el segundo numero *)     writeln('Ingrese el segundo numero:');    readln(digit);   (* Se lee el primer digito *)    b.tope := 0;     (* Se inicializa el tope *)    WHILE (digit IN [0..9]) AND ((b.tope < MaxDig) OR (b.tope = MaxDig)) DO         BEGIN     (* Mientras pertenesca al intervalo 0..9 y no se termine el array *)             b.tope := b.tope + 1;  (* Se incrementa el tope *)             b.digitos[b.tope] := digit;    (* Se almacena el digito en la celda correspondiente *)             readln(digit)              (* Se lee el siguiente digito *)         END;      (* Si un array tiene mas digitos que otro, entonces al que tiene menos hay que agregarle ceros al principio *)    (* Hasta que ambos tengan la misma longitud, de esa manera la suma se hará con mayor facilidad *)     IF (a.tope > b.tope) THEN BEGIN       FOR i := b.tope DOWNTO 1 DO BEGIN           temp := b.digitos[i+(a.tope-b.tope)];           b.digitos[i+(a.tope-b.tope)] := b.digitos[i];           b.digitos[i] := temp;           b.tope := b.tope + (a.tope - b.tope);           END; (* FOR *)       FOR i := 1 TO (a.tope - b.tope) DO           b.digitos[i] := 0;       END   (* if *)       ELSE IF (b.tope > a.tope) THEN BEGIN               FOR i := a.tope DOWNTO 1 DO BEGIN                   temp := a.digitos[i+(b.tope-a.tope)];                   a.digitos[i+(b.tope-a.tope)] := a.digitos[i];                   a.digitos[i] := temp;                   a.tope := a.tope + (b.tope-a.tope);                   END;   (* FOR *)               FOR i := 1 TO (b.tope - a.tope) DO                    a.digitos[i] := 0;               END; (* ELSE IF *)        c.tope := 0;    FOR i := 1 TO (a.tope) DO BEGIN        c.tope := c.tope + 1;        c.digitos[i] := 0        END;     (* Ahora se le indicará a la máquina que sume los arreglos a y b como lo hacíamos en la escuela: digito a digito *)    (* empezando por las unidades y de derecha a izquierda *)    (* hay que considerar también el acarreo de las decenas, que por defecto, *)    (* se inicializa en cero *)     acarreo := 0;    FOR i := (a.tope) DOWNTO 1 DO BEGIN        suma := a.digitos[i] + b.digitos[i] + acarreo;        IF (i = 1) AND (suma DIV 10 = 1) THEN BEGIN  (* caso excepcional: si al sumar el primer digito de a con el de b, el resultado es 10 o más, *)           c.digitos[c.tope+1] := c.digitos[c.tope];  (* entonces, al array c se le agrega una cifra más al principio: la cifra del acarreo *)           c.tope := c.tope + 1;           c.digitos[2] := suma MOD 10;           c.digitos[1] := suma DIV 10        END (* IF *)        ELSE BEGIN   (* sino, entonces sumamos cifra con cifra y almacenamos las unidades en la celda del array c, y las decenas que sobren en acarreo *)                 c.digitos[i] := suma MOD 10;                 acarreo := suma DIV 10             END;  (* ELSE *)        END;  (* FOR *)     (* Para terminar, mostramos el resultado de la suma en pantalla *)    FOR i := 1 TO (c.tope) DO        write(c.digitos[i]);        readln(i); END.  :rolleyes: Bueno, este código me funcionó, pero me gustaría saber si uds. piensan que es una buena forma de programar o si hay cosas que se pueden mejorar u obviar...Ah! Me olvido de decirles que yo programo en free pascal 2.2.2.
  :good: Saludos

Navegación

[0] Índice de Mensajes

Ir a la versión completa