Ir ao conteúdo
  • Cadastre-se
marcos12345

C Multiplicar números muito grandes

Recommended Posts

Preciso de ajuda com esse problema em c que é multiplicar números muito grande em c .

Eu conquir fazer apenas a parte de quando multiplica os numero mas na hora de somar não conseguir por exemplo

Digite um numero
123
Digite outro numero
123
m = 9
m = 6
m = 3
m = 6
m = 4
m = 2
m = 3
m = 2
m = 1 

ou seja esta fazendo 3 x 3=9, 3 x 2=6, 3 x 1=3, 2 x 3=6, 2 x 2=4, 2 x 1=2, 1 x 3=3, 1 x 2=2, 1 x 1=1;

eu não estou conquindo fazer soma.

          369

        246

      123    

    =15129

olha o código que eu fiz:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    char n1[1000],n2[1000];
    int tamn1,tamn2,i,j,ai,bi,m,ts=0;

    printf("Digite um numero\n");
    scanf("%s",n1);
    printf("Digite outro numero\n");
    scanf("%s",n2);

    tamn1=strlen(n1);
    tamn2=strlen(n2);

    for(i=tamn2-1; i>=0; i--){
        for(j=tamn1-1; j>=0; j--){
            if(i>=0){
                ai=n1[j]-'0';
            }else{
                ai=0;
            }
            if(j>=0){
                bi=n2[i]-'0';
            }else{
                bi=0;
            }
            m = ((ai*bi)+ts);
            if(j>0){
                ts=m/10;
                m=m%10;
            }else{
                ts=0;
            }
            printf("m = %d\n",m);
        }
    }
    return 0;
}

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante

@marcos12345  Olá. Vê se é isso q você quer. Você está lendo os números como sendo strings, por isso é necessário converter essas strings contendo números inteiros para o tipo int, usando a função atoi para isso.

 

int soma = atoi(n1) + atoi(n2);

printf("\nSoma: %d\n\n", soma);

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
55 minutos atrás, giu_d disse:

@marcos12345  Olá. Vê se é isso q você quer. Você está lendo os números como sendo strings, por isso é necessário converter essas strings contendo números inteiros para o tipo int, usando a função atoi para isso.

 


int soma = atoi(n1) + atoi(n2);

printf("\nSoma: %d\n\n", soma);

 

disso eu sei mas o problema é com somar na multiplicação por exemplo

          12

          12 

          24

        12  

        144

minha duvida é como fazer:

        24

      12  +

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá ...

Gostei muito dessa ideia ...

e vou logo dizendo que sem definir o sinal na estrutura "não é possível" consolidar sua(s) operação(ões) de maneira fácil.

 

fragmento: Post #1

...
char n1[1000],n2[1000];

...

Assim: Acredito ser mais fácil

  1. [0,...,'+', '1','2','3']

ou

  1. ['1','2','3','+', ...,0]

Ou seja, é importante saber o sinal.

  • Primeiro antes de qualquer operação se investiga o sinal;
  • Saberá-se-a o tamanho do número, operação de sinais;
  • Introduz algo inerente a operação;
  • E não mais haverá necessidade de contar os caracteres com strlen (...);
  • Operação se dar pela direita para esquerda.

A partir disso, você faz as conversões ou operar em cima dos caracteres, simplesmente destacando o sinal.

Exemplo:

  1. De multiplicação: 

 123

x   5

 

  • M[0, ...,0] = A[0,...,'+','5'] X B[0,...,'+', '1','2','3']
  • Ao escanear pelo sinal: A tem a  no máximo 1 dígito(s), B tem b no máximo 3 dígito(s).
  • A[999] * B[999]: '5' * '3', que convertido é igual a 3 * 5
  • M[999] = 15 % 10 + '0' = '5'
  • e carry¹ = 15 / 10 = 1
  • A[999] * B[998]: '5' * '2', que convertido é igual a 5 * 2
  • M[998] = (10 + carry¹) % 10 + '0' = '1'
  • e carry¹ = (10 + carry¹)/10 = 1 
  • ...

# O número de somas é igual ao número de casa decimais no multiplicador

O número de zeros no final de M no início de cada multiplicação é igual a valor da casa decimal no multiplicador, assim por exemplo se a = 0, então M[999] tem por unidade o resultada da primeira multiplicação, porém se a = 1, então M[999] = 0, se a = 2 então M[998...999] = 0, se a = 3 então M[997...999] = 0 ...,  o primeiro resultado da multiplicação consequente é imediatamente o próximo M[ X ] depois dos zeros da direita para esquerda. 

 

 

Parece complicado, alguém deve ter uma ideia melhor que essa, contudo essa é a minha.

Espero ter ajudado, boa sorte.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
49 minutos atrás, AnsiC disse:

Olá ...

Gostei muito dessa ideia ...

e vou logo dizendo que sem definir o sinal na estrutura "não é possível" consolidar sua(s) operação(ões) de maneira fácil.

 

fragmento: Post #1


...
char n1[1000],n2[1000];

...

Assim: Acredito ser mais fácil

  1. [0,...,'+', '1','2','3']

ou

  1. ['1','2','3','+', ...,0]

Ou seja, é importante saber o sinal.

  • Primeiro antes de qualquer operação se investiga o sinal;
  • Saberá-se-a o tamanho do número, operação de sinais;
  • Introduz algo inerente a operação;
  • E não mais haverá necessidade de contar os caracteres com strlen (...);
  • Operação se dar pela direita para esquerda.

A partir disso, você faz as conversões ou operar em cima dos caracteres, simplesmente destacando o sinal.

Exemplo:

  1. De multiplicação: 

 123

x   5

 

  • M[0, ...,0] = A[0,...,'+','5'] X B[0,...,'+', '1','2','3']
  • Ao escanear pelo sinal: A tem a  no máximo 1 dígito(s), B tem b no máximo 3 dígito(s).
  • A[999] * B[999]: '5' * '3', que convertido é igual a 3 * 5
  • M[999] = 15 % 10 + '0' = '5'
  • e carry¹ = 15 / 10 = 1
  • A[999] * B[998]: '5' * '2', que convertido é igual a 5 * 2
  • M[998] = (10 + carry¹) % 10 + '0' = '1'
  • e carry¹ = (10 + carry¹)/10 = 1 
  • ...

# O número de somas é igual ao número de casa decimais no multiplicador

O número de zeros no final de M no início de cada multiplicação é igual a valor da casa decimal no multiplicador, assim por exemplo se a = 0, então M[999] tem por unidade o resultada da primeira multiplicação, porém se a = 1, então M[999] = 0, se a = 2 então M[998...999] = 0, se a = 3 então M[997...999] = 0 ...,  o primeiro resultado da multiplicação consequente é imediatamente o próximo M[ X ] depois dos zeros da direita para esquerda. 

 

 

Parece complicado, alguém deve ter uma ideia melhor que essa, contudo essa é a minha.

Espero ter ajudado, boa sorte.

 

 

Não conseguir entender é muito complexo para mim kkkk

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aqui está como eu consegui fazer, veja se consegue entender:

#include <stdio.h>
#include <string.h>

int main()
{
    int tamn1, tamn2, i, j, ai, bi, ts;
    unsigned char n1[1000], n2[1000];
    unsigned char r[1000] = {0};
    
    printf("Digite um numero\n");
    scanf("%s",n1);
    printf("Digite outro numero\n");
    scanf("%s",n2);
    
    tamn1=strlen(n1);
    tamn2=strlen(n2);
    
    ts = 0;
    for(j = tamn2-1; j >= 0; j--){
        bi = n2[j] - '0'; //j nunca é menor que 0
        for(i = tamn1-1; i >= -1; i--){ //Vai até -1 para somar o último ts
            ai = i >= 0 ? n1[i] - '0' : 0; //valor depende se i é maior ou igual a 0
            r[j+i+1] += bi * ai + ts; // multiplica e soma aos anteriores
            ts = r[j+i+1] / 10;
            r[j+i+1] = r[j+i+1] % 10;
        }
    }
    
    //Transforma números em caracteres
    r[tamn1 + tamn2] = '\0';
    for(i = 0; i < tamn1+tamn2; i++){
        r[i] += '0';
    }
    
    //Remove zero a esquerda
    for(i = 0; i < tamn1+tamn2-1 && r[i] == '0'; i++);
    strcpy(r, &r[i]);
    
    printf("\n%s\n", r);
    
    return 0;
}

 

Note que a quantidade de dígitos do resultado sempre será igual a soma das quantidades dos dígitos dos 2 números, ou 1 dígito a menos (caso não carregue nada na última multiplicação).

 

E o segredo é notar que o resultado da multiplicação atual é somando na casa j + i + 1 do vetor do resultado.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, marcos12345 disse:

Não conseguir entender é muito complexo para mim kkkk

@marcos12345 Desculpa-me, é que estou sem tempo para fazer uma demostração com bons códigos, e não quero postar nada ruim de se ver. Quanto disponível vou tentar escrever um programa suficientemente modulado: De código reaproveitável com funções como manda o figurino, pois gostei bastante desse problema e não esquecerei

 

Boa Sorte!

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 horas atrás, isrnick disse:

Aqui está como eu consegui fazer, veja se consegue entender:


#include <stdio.h>
#include <string.h>

int main()
{
    int tamn1, tamn2, i, j, ai, bi, ts;
    unsigned char n1[1000], n2[1000];
    unsigned char r[1000] = {0};
    
    printf("Digite um numero\n");
    scanf("%s",n1);
    printf("Digite outro numero\n");
    scanf("%s",n2);
    
    tamn1=strlen(n1);
    tamn2=strlen(n2);
    
    ts = 0;
    for(j = tamn2-1; j >= 0; j--){
        bi = n2[j] - '0'; //j nunca é menor que 0
        for(i = tamn1-1; i >= -1; i--){ //Vai até -1 para somar o último ts
            ai = i >= 0 ? n1[i] - '0' : 0; //valor depende se i é maior ou igual a 0
            r[j+i+1] += bi * ai + ts; // multiplica e soma aos anteriores
            ts = r[j+i+1] / 10;
            r[j+i+1] = r[j+i+1] % 10;
        }
    }
    
    //Transforma números em caracteres
    r[tamn1 + tamn2] = '\0';
    for(i = 0; i < tamn1+tamn2; i++){
        r[i] += '0';
    }
    
    //Remove zero a esquerda
    for(i = 0; i < tamn1+tamn2-1 && r[i] == '0'; i++);
    strcpy(r, &r[i]);
    
    printf("\n%s\n", r);
    
    return 0;
}

 

Note que a quantidade de dígitos do resultado sempre será igual a soma das quantidades dos dígitos dos 2 números, ou 1 dígito a menos (caso não carregue nada na última multiplicação).

 

E o segredo é notar que o resultado da multiplicação atual é somando na casa j + i + 1 do vetor do resultado.

conseguir entender valeu cara

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 11/06/2018 às 21:01, marcos12345 disse:

for(i = tamn1-1; i >= -1; i--){ //Vai até -1 para somar o último ts

cara eu tava olhando direito aqui e eu não conseguir entender essa parte por que é que ele vai ate o i ser >= a -1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para você entender, como exemplo vamos multiplicar 911 por 9 (cujo resultado é 8199).

 

911 seria o n1 no algoritmo, e tem 3 dígitos, veja o que acontece se fizermos apenas as operações com estes 3 dígitos:

 

8 0 0      <--- ts da operação anterior

  911   <--- n1

x    9   <--- n2

 199    <--- r

 

O resultado foi 199, pois o último ts = 8 não foi somado para obter o último dígito, que obviamente está errado. Para corrigir isso nós devemos realizar uma última operação de multiplicação, colocando um quarto dígito, igual a 0, a esquerda do número 911, ficando igual a 0911.

 

0 8 0 0      <--- ts da operação anterior

  0911   <--- n1

  x    9   <--- n2

 8199    <--- r

 

Ou seja, deve ir 1 casa além para esquerda, do número n1, para fazer a multiplicação por 0, e somar o último ts, caso ele tenha um valor diferente de 0. Por isso vai até a posição i = -1.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×