Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
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

@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.

 

 

Editado por AnsiC
Correção

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.

Editado por isrnick
Modificar para remover todos os zeros a esquerda
  • 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.

Editado por isrnick

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






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

×