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 */
/********************************************************/