int
ou mesmo long
int
, já que estas armazenam valores de magnitude limitada. Uma
técnica é utilizar para cada número um vetor que contenha em cada
componente um dígito do número.
#define MAX_DIGITOS 60
-321938492382734
será armazenado em um vetor como
1 | 0 | 0 | ... | 0 | 0 | 3 | 2 | 1 | 9 | 3 | 8 | 4 | 9 | 2 | 3 | 8 | 2 | 7 | 3 | 4 |
Note que o número de casas de um vetor que armazena um número deve ser
MAX_DIGITOS+1
, devido à casa reservada para o sinal.
void zera (int numero[]);
numero
com zeros.
int soma (int num1[], int num2[], int res[]);
num1
ao vetor num2
(considere que ambos os números sejam positivos ou ambos sejam
negativos) e armazena o resultado no vetor res
. No
caso de ser detectado overflow (ocorreu "vai um" quando da soma
dos dígitos mais significativos) a função deve devolver valor 1
(um). Caso contrário, a função deve devolver valor 0 (zero).
void subtrai (int num1[], int num2, int res[]);
num1
do vetor num2
, ou
seja, calcula num1 - num2
(considere que ambos os
números sejam positivos ou ambos sejam negativos e que o módúlo
de num1
seja maior ou igual ao módulo de
num2
) e armazena o resultado no vetor res
.
int multiplica (int num1[], int num2[], int res[]);
num1
pelo vetor
num2
e armazena o resultado no vetor
res
. Para fazer a multiplicação, utilize o
algoritmo usual de multiplicar dois números (é claro que você
terá que usar a função soma
). No caso de ser detectado
overflow (ocorreu "vai um" quando da soma dos dígitos mais
significativos) a função deve devolver valor 1 (um). Caso
contrário, a função deve devolver valor 0 (zero).
int divide (int num1[], int num2[], int quoc[], int resto[]);
num1
pelo vetor num2
e
armazena o quociente no vetor quoc
e o resto no
vetor resto
. Para fazer a divisão, faça subtrações
sucessivas utilizando a função subtrai
. No caso do
vetor num2
ser zero, a função deve devolver valor 1
(um). Caso contrário, a função deve devolver valor 0 (zero).
Sua função divide
deve funcionar como o / e o % do
C
quando num1
ou num2
são
negativos.
int maior_igual (int num1[], int num2[]);
num1 >= num2
e 0
(zero) caso contrário.
int nulo (int num[]);
num = 0
e 0 (zero)
caso contrário.
void copia_num (int num1[], int num2[]);
num2
em num1
.
int incrementa (int numero[]);
numero
. Devolve 1 (um) caso haja overflow e 0 (zero)
caso contrário.
FILE *arq;
A variável arq
deve ser inicializada no início do seu
programa através do seguinte trecho de código.
if ((arq = fopen("entrada.txt", "r")) == NULL) { printf("Erro na abertura do arquivo de entrada!\n"); return 1; }
onde entrada.txt
é o nome do arquivo de onde serão lidos
os dados.
Depois disso, a leitura do arquivo entrada.txt
pode ser
feita de maneira semelhante à leitura do teclado. A única diferença é
que deve-se usar a função fscanf
da biblioteca
stdio.h
no lugar da função scanf
. A função
fscanf
tem um parâmetro a mais que a scanf
:
o primeiro parâmetro, que indica o arquivo de onde quer-se fazer a
leitura. Assim, por exemplo, o seguinte trecho de programa (depois das
declarações acima) lê uma seqüência de 20 números reais do arquivo
entrada.txt
e a guarda em um vetor v
:
for (i=0; i<20; i++) fscanf(arq, "%lf", &v[i]);No caso deste exercício-programa, o arquivo de entrada deve ser lido caracter a caracter (utilizando-se o formato de leitura
"%c"
), pois os números são muito grandes para serem lidos
com os formatos numéricos do C
. O seu programa deve
converter os caracteres lidos para números.
Os operadores permitidos são: + (adição), - (subtração), * (multiplicação), / (divisão inteira) e % (resto da divisão inteira).
Aqui você encontra um exemplo de arquivo de entrada. Teste o seu programa com esse arquivo!
No seu programa, para detectar se todas as linhas do arquivo de
entrada já foram lidas, use a função feof
, que recebe
como parâmetro o indicador de um arquivo e devolve 1 (true) se
não há mais nada para ser lido no arquivo de entrada e 0
(false) se ainda há algo no arquivo para ser lido. Assim, o seu
programa deverá conter uma repetição do seguinte tipo no programa principal:
while (!feof(arq)) { /* processamento de uma linha do arquivo */ ... }Cuidado com linhas em branco no fim do seu arquivo de entrada. Elas podem fazer diferença no seu programa! Abaixo falamos mais sobre isso.
entrada.txt
(isto é, depois de digitar o
arquivo, escolha a opção save as e escolha como nome do arquivo
entrada.txt
).
Certifique-se que o seu arquivo não contém linhas em branco no final, pois isso pode fazer diferença no seu programa.
char le_numero (FILE *arq, int numero[]);
arq
e guarda no vetor
numero
. A função devolve o último caractere lido,
ou o caractere '#' se houver algum erro na leitura.
void imprime_numero (int numero[]);
numero
.
Assim, a saída do seu programa para o arquivo de entrada acima deverá ser:
Operacao 1: 999999 + 1 = 1000000 Operacao 2: -999999 + -1 = -1000000 Operacao 3: -100000 - 1 = -100001 Operacao 4: 100000 - 1 = 99999 Operacao 5: -999999 - 1 = -1000000 Operacao 6: 999999999999999999999999999999999999999999999999999999999999 + 3 Overflow!! Operacao 7: 123456789123456789 + 123456789 = 123456789246913578 Operacao 8: 123456789123456789 - 123456789 = 123456789000000000 Operacao 9: 98765432 - 123456789 = -24691357 Operacao 10: 1234567 * 987654321 = 1219325432114007 Operacao 11: -23456789 * 987654 = -23167191483006 Operacao 12: 987654321987654321987654321987654321987654321987654321 * 987654321 Overflow!! Operacao 13: 2222 / 2 = 1111 Operacao 14: 2222 % 2 = 0 Operacao 15: 1867 % 0 Divisao por zero! Operacao 16: 987654321 / 123456789 = 8 Operacao 17: 87654321 / -23456789 = -3 Operacao 18: 324567 / 0 Divisao por zero! Operacao 19: 987654321 % 123456789 = 9
Aqui vai uma sugestão estratégica. Primeiro, escrevam e testem as funções sem se preocuparem com arquivos: leiam números do teclado, como uma seqüência de caracteres, e imprimam o resultado de cada uma das operações na tela. Depois que as funções das operações estiverem funcionando, passem à leitura do arquivo.
Agora uma sugestão de divisão de trabalho. Um dos dois participantes
da dupla pode ficar encarregado de escrever e testar as funções
soma
, zera
, multiplicação
e
imprime_numero
, bem como a parte do programa principal
que trata das operações de adição e multiplicação. O outro
participante pode ficar com as funções subtrai
,
copia_num
, nulo
, maior_igual
,
incrementa
e divide,
bem como com a parte do
programa principal que trata das operações de subtração e divisão. Os
dois participantes da dupla podem escrever juntos a parte de leitura
do arquivo, que sempre é uma aventura. E podem depurar (tirar os
erros) do programa completo juntos.
Bom divertimento!!!!
/********************************************************/ /* Fulano e Beltrano de Tal */ /* Exercicio-Programa xx */ /* Curso yy - Turma zz -- Professor: Ciclano de Tal */ /********************************************************/