Ir para conteúdo
Fórum Script Brasil

isrnick

Membros
  • Total de itens

    70
  • Registro em

  • Última visita

Tudo que isrnick postou

  1. isrnick

    Ajuda em C

    Você provavelmente leu que números do tipo int com sinal ficam no intervalo de [−32,768, +32,767], e sem sinal (unsigned) o intervalo é [0, +65,535]. Se você tiver aprendido sobre números binários, vai saber que estes números são definidos assumindo que nesse caso os números inteiros tem um total de 16 bits (= 2 bytes) na forma binária. Mas na verdade o que o padrão define é que o tipo int deve ter pelo menos 16 bits, ou seja, o tipo int ter mais que 16 bits é aceitável. O GCC arquitetura x86, que provavelmente é o compilador que você está usando, vem configurado pra o int ter 32 bits (se não me engano você pode mudar essa configuração), Logo, nesse caso os intervalos serão [−2,147,483,648, +2,147,483,647] para int com sinal e [0, +4,294,967,295] para unsigned. Segue abaixo um código simples para verificar o número de bits do tipo int no seu compilador: #include <stdio.h> int main(){ printf("O tipo int tem %d bits.\n", sizeof(int)*8); return 0; }
  2. Para armazenar uma string em C você precisa de um vetor de chars, não um único char. Logo mude: char nome; Para algo como: char nome[100];
  3. Não, você pode dividir o número várias vezes por 10, e parar quando o número for menor que 10 (ou seja quando sobrar apenas 1 dígito). Veja: 42547 / 10 = 4254 4254 / 10 = 425 425 / 10 = 42 42 / 10 = 4 4 é menor que 10, logo paramos de dividir por 10 aqui, e 4 é o dígito mais significativo do número original.
  4. Só tinha um probleminha nessa linha "for k in matrizB:", pois aqui você não quer que k assuma como valor linhas inteiras da matrizB... O correto seria "for k in range(sizeLB):" ou "for k in range(sizeCA):". Corrigi isso, e aproveitei pra fazer a função também poder multiplicar matrizes não quadradas: def prodMatrix(matrizA, matrizB): """Multiplica duas matrizes.""" sizeLA = len(matrizA) sizeCA = len(matrizA[0]) # deve ser igual a sizeLB para ser possível multiplicar as matrizes sizeCB = len(matrizB[0]) matrizR = [] # Multiplica for i in range(sizeLA): matrizR.append([]) for j in range(sizeCB): val = 0 for k in range(sizeCA): val += matrizA[i][k]*matrizB[k][j] matrizR[i].append(val) return matrizR A lógica é essa, mas não testei a função. Edit: Testei e encontrei mais erros, era necessário criar as linhas na matriz a cada iteração, e adicionar os valores em cada linha da matrizR, corrigi isso e agora funciona corretamente.
  5. Acho que a maneira mais simples seria deslocar os bits pra esquerda, pra posicionar na casa correta e somar. Mas você está armazenando o bit menos significativo na posição 0 ou na posição 7 do vetor? Assumindo que o menos significativo está na posição 0 ficaria algo assim: uint8_t byte = motores[0] + (motores[1] << 1) + (motores[2] << 2) + (motores[3] << 3) + (motores[4] << 4) + (motores[5] << 5) + (motores[6] << 6) + (motores[7] << 7); ou int i; uint8_t byte = 0; for (i = 0; i<8; i++) byte += motores[i] << i;
  6. Então você poderia mudar a lógica... Fora dessa função você cria um vetor com números indo de 0 a Count-1 em cada posição. Aí usa random_shuffle ( http://en.cppreference.com/w/cpp/algorithm/random_shuffle ) pra embaralhar o vetor. Então nessa função você muda pra guardar os próximos 2 itens do vetor em sequência toda vez que ela for chamada, pra fazer isso tem várias maneiras possíveis, você poderia passar o vetor e a posição atual para a função, poderia passar direto os 2 próximos valores do vetor para a função, poderia fazer o vetor ser global e passar apenas posição atual, etc...
  7. O "Count" vai ser sempre 10? Se não, tem um valor máximo?
  8. No Windows basta salvar o arquivo do código com a extensão .pyw ao invés de .py . Com extensão .py o programa é executado usando python.exe que automaticamente usa o prompt de comandos (cmd), já assumindo que ele será usado como o meio de entrada e exibição de dados do programa. Mas a extensão .pyw é associada ao pythonw.exe para executar o código, que é o que se deseja usar para rodar programas com interface gráfica, pois ele não usa o prompt, e se você não programar nenhuma interface gráfica para ser exibida o resultado é que o programa é rodado sem exibir nada, e você só vai ver que um programa está rodando pelo processo pythonw.exe no Gerenciador de Tarefas.
  9. isrnick

    Ajuda no programa

    Eu ainda nem ajudei com nada... :-P Já descobriu como faz?
  10. isrnick

    Ajuda no programa

    Pode usar a biblioteca NumPy?
  11. Ex: Count = 10 e IndexA = 5 rand()%(Count-1) = [0 a 8] rand()%(Count-1) + 1 = [1 a 9] IndexA + rand()%(Count-1) + 1 = [6 a 14] (IndexA + rand()%(Count-1) + 1)%Count = [6 a 9] ou [0 a 4] Logo, IndexB nunca será igual a 5, mas pode ser qualquer outro número de 0 a 9.
  12. Tenta assim: bool CPVP::GetFighters(PVP_DATA * lpInfo, int Count) { int IndexA = rand()%Count; int IndexB = (IndexA + rand()%(Count-1) + 1)%Count; lpInfo-> DuelistA = IndexA; lpInfo-> DuelistB = IndexB; if (Count < 2) { return false; } return true; } Edit: Faltou somar +1 dentro do parênteses, agora deve funcionar corretamente, IndexA e IndexB sempre no intervalo mas nunca iguais.
  13. Sai do terminal do Python, roda o programa assim no prompt (na pasta onde tá o arquivo bigdigits.py e assumindo que a pasta do Python tá no PATH do seu sistema operacional): python bigdigits.py 420 E veja se funciona...
  14. Vamos lá... Precisamos obter a parte inteira de um número armazenado em uma variável float... Vamos usar o exemplo da imagem que você postou: número = (-248.75)10 = (1-10000110-11110001100000000000000)bin = (C378C000)H Pra obter apenas o bit do sinal é simples basta deslocar o número em binário de 31 bits para direita (>> 31) e só o bit do sinal sobrará, então basta checar: - Se: bit do sinal = 1 => sinal = - - Se: bit do sinal = 0 => sinal = + Nesse caso: bit do sinal = número >> 31 = (00000001)H = 1 logo, sinal = - Para obter um inteiro contendo apenas os 8 bits do expoente da variável float, podemos deslocar o binário do float de >> 23 para eliminar a parte da mantissa, e em seguida fazer a operação AND (&) com FFH = 1111 11112 para eliminar o bit do sinal. Mas lembre-se que esse inteiro terá valor entre 0 e 255, então precisamos subtrair 127 desse número para finalmente obter o valor expoente. No nosso exemplo: 11000011 01111000 11000000 00000000 >> 23 = 00000000 00000000 00000001 10000110 00000000 00000000 00000001 10000110 & 0xFF = 00000000 00000000 00000000 10000110 = 134 expoente = 134 - 127 = 7 Agora para obter a fração da mantissa podemos fazer a operação AND do binário do float com 7FFFFFH (= binário com 1 em todos os 23 bits mais a direita), para eliminar os bits do sinal e do expoente. E então somar com 800000H (= binário com 1 apenas no bit 24) para recuperar bit da parte inteira da mantissa que havia sido omitida. Ficando: 11000011 01111000 11000000 00000000 & 0x007FFFFF = 00000000 01111000 11000000 00000000 00000000 01111000 11000000 00000000 + 0x00800000 = 00000000 11111000 11000000 00000000 Lembrando que o ponto (.) da mantissa fica entre os bits 24 e 23, temos que: mantissa = (1.111100011)2 Juntando tudo resulta que: número = - (1.111100011 * 27)2 Se nós deslocarmos o ponto para zerar o expoente, fica: número = - (11111000.11 * 20)2 = - [ (11111000)2 + (0.11)2 ] = - [ (248)10 + (0.75)10 ] = (-248.75)10 Obtendo o número decimal original. Para fazer isso computacionalmente, assumimos que o ponto (.) está fixo na entre os bits 23 e 24, podemos deslocar o binário para esquerda do valor do expoente (<< expoente), assim obteremos o número na forma com o expoente zerado. No nosso exemplo o expoente é igual a 7, então: 00000000 1.1111000 11000000 00000000 << 7 = 01111100 0.11000000 0000000 00000000 Agora temos as partes inteira e fracionária separadas do número na forma binária, a esquerda e a direita respectivamente do nosso ponto imaginário (ou seja, a esquerda do bit 23 está a parte inteira do número e direita (incluindo o próprio) está a parte fracionária). Precisamos apenas da parte inteira nesse exercício, podemos então eliminar a parte fracionária deslocando o número binário de >> 23, e sobra só a parte inteira, que é o que nós queremos. 01111100 011000000 0000000 00000000 >> 23 = 0000000 0000000 0000000 11111000 Logo: Parte inteira do número o sem sinal = (11111000)2 = (248)10 Mas observe que fizemos 2 deslocamentos em seguida em direções opostas no mesmo binário << 7 e >> 23, poderíamos então calcular o deslocamento total = 23 - 7 = 16 e fazer um único deslocamento >> 16. 00000000 11111000 11000000 00000000 >> 16 = 0000000 0000000 0000000 11111000 Ou, de forma geral, para obter apenas a parte inteira do número, basta deslocar o número binário de >> (23 - expoente). Finalmente basta multiplicar o resultado por -1 ou +1 dependendo do valor do bit do sinal para obter a parte inteira do número que poderá ser comparada com o outro número inteiro no programa. A lógica está aí, fora isso a única coisa que você precisa para fazer o programa é uma maneira para conseguir fazer operações lógicas com o número float em forma binária, já que se você tentar fazer diretamente com a variável float vai gerar um erro na compilação. O que você precisa é obter o valor binário da variável float numa variável int. E para isso podemos usar um ponteiro do tipo unsigned int e armazenar nele a referência da variável float (com um cast para ponteiro do tipo unsigned int). Dessa maneira: unsigned int *fvaluebin; fvaluebin = (unsigned int *)&fvalue; //Então algo assim não gera erro pois o //ponteiro é do tipo int: *fvaluebin = *fvaluebin & 0xFFFFFFFF; Também é bom notar que a variável float só pode armazenar no números inteiros de máximo +/- 224 - 1 = 16777215 sem que haja perda de precisão, então esse é o maior número inteiro que pode ser comparado de forma confiável. Acima disso o float passa a trucar os dígitos menos significativos (na forma binária).
  15. Esse exercício não é trivial. Primeiro é preciso entender como números reais são armazenados em variáveis float: Tendo um número real você primeiro converte para o modo binário, separando a parte inteira e a parte fracionária, converte cada uma respectivamente para a forma binária (para o nosso caso não é importante saber como a parte fracionárias é convertida para binário, mas se tiver interesse basta pesquisar). Por exemplo, convertendo o número decimal 12.375 para binário fica: (12.375)10 = (12)10 + (0.375)10 = (1100)2 + (0.011)2 = (1100.011)2 Temos em binário então isto: 1100.011 = 1100.011 * 20 O ponto flutuante do número deve então ser deslocado para a direita ou esquerda tal que o ponto (.) fique imediatamente após o primeiro bit mais a esquerda (mais significativo) que for igual 1 (ou seja queremos o número na forma de notação científica), e ajustar o expoente do multiplicador 2 correspondentemente. Ficando: 1100.011 * 20 = 1.100011 * 23 Nosso número é positivo então o bit 32 armazena 0. Temos que o expoente é 3, mas os 8 bits que armazenam o expoente no float, guardam um número binário indo de 0 a 255, para que seja possível armazenar expoentes negativos devemos usar o ponto central desse intervalo (= 127) como sendo o expoente 0, logo somamos o 127 ao valor do nosso expoente para obter o número a ser armazenado nos 8 bits do expoente. Ou seja: 127 + 3 = (130)10 = (10000010)2 E por fim apenas a parte fracionária da mantissa (nesse caso .100011) é armazenada nos 23 bits restantes do float, de modo que o ponto (.) fictício ficaria a esquerda dos 23 bits e os dígitos binários da parte fracionária são armazenados começando no bit 23 e indo para a direita. (O 1 da parte inteira do número binário é omitido, e deve ser assumido novamente quando o processo é invertido.) O resultado final então fica: 0-10000010-10001100000000000000000 Ou em hexadecimal: 41460000H Ok, vou para por aqui por agora, mais tarde posto mais explicações, mas primeiro me diga se conseguiu entender. O que precisa ser feito é o processo inverso então é preciso entender isto (talvez você já consiga até pegar a ideia pra fazer o código).
  16. isrnick

    Operadores Bitwise

    Algum motivo pelo qual você prefere usar o número 1 na forma octal 01? Normalmente hexadecimal é preferido quando lidando com binários. O primeiro parâmetro desse for não parece ter função alguma para a lógica do seu programa: for ( \* value1 >>= 1 *\ ; value != 0; value >>= 1){ Então, poderia ser removido. E atualmente, a primeira execução do for apenas repete o que já tinha sido declarado inicialmente fora do ciclo ("count = 1;" e "last = value & 01;") e incrementa o índice ("++idx"), já que "value" ainda não foi deslocado e atualizado.
  17. isrnick

    Operadores Bitwise

    Se tiver qualquer dúvida sobre o código é só perguntar.
  18. Primeiro, você está fazendo o usuário digitar o valor do último número da sequência de n elementos com progressão aritmética (an), sendo que o programa podia calculá-lo, visto que an = a1 + (n-1) * r; Mas se o que você quer é que o programa imprima a sequência inteira, mostrando todos o elementos, para qualquer tamanho de n, vai precisar usar ciclos. Você já aprendeu a usar ciclos ("while", "for", "do while")?
  19. isrnick

    Operadores Bitwise

    Para postar códigos aperte o botão <> no topo do campo de respostas, este é o botão da tag CODE. Acho que é melhor sempre armazenar o bit do ciclo anterior e comparar com o atual, e contar se forem diferentes. Aqui eu fiz uma solução: unsigned int findsaw(int value) { int previous, index = 0, count = 0, maxcount = 0, bigger = 0; previous = value & 0x01; for (value >>= 1; value != 0; value >>= 1) { if( (value & 0x01) != previous) count++; else { if (count > maxcount) { maxcount = count; bigger = index - count; } count = 0; } previous = value & 0x01; index++; } if (count > maxcount) { maxcount = count; bigger = index - count; } return bigger; }
  20. Teste sem as partes comentadas abaixo, pois acredito que são desnecessárias e são o que estão causando o problema. case 1: { printf ("\nInforme o código?:"); scanf ("%d", &dado); for (w = 0; w <= i; w++) { if (dado == contatos[w].codigo) { printf ("\n%i", contatos[w].codigo); printf ("\n%s", contatos[w].nome); printf ("\n%i", contatos[w].telefone); printf ("\n%s", contatos[w].email); printf ("\n\nDeseja remover o cadastro acima?"); printf ("\n1 - Sim"); printf ("\n2 - Não"); printf ("\nOpção: "); scanf ("%i", &removecontrato); if (removecontrato == 1) { for (int exclusor=w; exclusor < i; exclusor++) //aqui vamos simplesmente começar do w pois ele é o registro que queremos excluir. { contatos[exclusor].codigo = contatos[exclusor+1].codigo; strcpy(contatos[exclusor].nome, contatos[exclusor+1].nome); contatos[exclusor].telefone = contatos[exclusor+1].telefone; strcpy(contatos[exclusor].email, contatos[exclusor+1].email); //ultimo++; } /*contatos[ultimo].codigo = NULL; strcpy(contatos[ultimo].nome, NULL); contatos[ultimo].telefone = NULL; strcpy(contatos[ultimo].email, NULL);*/ i--; } else if (removecontrato != 1 && removecontrato != 2) { printf ("\nOpção incorreta!"); } } } break; } "ultimo" está sendo incrementado mas não sei onde está sendo inicializado, mas ele é desnecessário de qualquer maneira, pois você não precisa colocar NULL na última posição, afinal i já foi decrementado (i--) então o que está nessa posição é irrelevante pois não será acessado, e quando um novo cadastro for feito o que está lá será sobrescrito/substituído. (Note que todas as posições do vetor de contatos que ainda não foram usadas já tem lixo lá, afinal o espaço da memória que foi alocado para armazenar os valores desta struct foi usado anteriormente por outros programas, então até você atribuir algum valor para os campos da struct o que tem lá é lixo e irrelevante para o programa. Logo, essa última posição virou só mais uma com valores que não são relevantes para o programa.) Edit: Aliás acredito que nesse for deveria ser apenas "menor que" (<) e não "menor ou igual a" (<=), correto? for (w = 0; w <= i; w++)
  21. Para postar códigos use a tag CODE apertando o botão <> no topo do campo de respostas, assim você preserva a formatação do código e evita que o fórum faça alterações nele. Primeiramente, a variável result não está sendo inicializada, então você tá somando os inversos dos fatoriais a algum valor lixo que está na memória onde result guarda seus valores. Result deveria começar com valor 1. Segundo, para imprimir número com ponto flutuante (float) deve-se usar %f ou %g ou %e no printf(), que é o caso da variável result. (%d é para números inteiros.) Corrigido o programa fica assim: #include<stdio.h> int main (void){ int i, n; float fat, result; printf("Digite um numero:\n"); scanf("%d", &n); result = 1.0; fat = 1.0; for(i=1; i<=n; i++){ fat = fat * i; result = result + 1.0/fat; } //printf("%f\n", fat); printf("O valor de E é: %f\n", result); return 0; } Note que fat estoura rapidamente conforme n cresce, indo para infinito, e ficando grande demais para ser armazenado numa variável do tipo float. Uma maneira de evitar isso seria fazer calcular o inverso do fatorial diretamente e somá-lo ao resultado, visto que: 1/n! = 1/1 * 1/2 * 1/3 * 1/4 *...* 1/(n-1) * 1/n E o inverso do fatorial converge para 0 quanto maior for n, e não estoura. Então o programa poderia ser feito assim: #include<stdio.h> int main (void){ int i, n; float invfat, result; printf("Digite um numero:\n"); scanf("%d", &n); result = 1.0; invfat = 1.0; for(i=1; i<=n; i++){ invfat = invfat * 1.0/i; result = result + invfat; } //printf("%f\n", invfat); printf("O valor de E é: %f\n", result); return 0; }
  22. Você não passou o valor armazenado na variável segundos para a função, então teria que incluir um quarto parâmetro no protótipo da função, que não seria uma ponteiro mas uma variável normal (colocando o "int segundos" no protótipo ao invés de definir dentro da função como você fez). E falta um "return 0;" no fim da função main.
  23. Dê um exemplo do que você deseja fazer, e poste sua tentativa/código. (Use o botão <> no topo do campo de resposta para postar códigos.)
  24. isrnick

    Ola ajuda nesse programa.

    stdin é abreviação do inglês standard input, ou entrada padrão em português. Nesse caso trata-se do 'fluxo' de entrada de dados na forma de texto através do console (prompt de comando). São digitados caracteres no prompt, e esses caracteres podem ser processados pelas funções das bibliotecas padrão do C (stdio.h, stdlib.h, etc) e outras. A função scanf() por exemplo obtém todos os caracteres digitados na entrada padrão até a última vez que Enter foi pressionado, e as processa dependendo dos parâmetros passados para a função (Ex: "%c%*c", &l) transformando de texto para o tipo correto (%d para inteiro, %f para float, etc) e armazenando os valores nas variáveis fornecidas. Mas o que não for utilizado pela função scanf fica lá na entrada padrão (se você digitar mais do que os parâmetros indicados na função esperam, por exemplo) podendo ser utilizados posteriormente por qualquer outra função de captura de entrada. A tecla Enter também produz um caractere quando pressionado, o caractere nova linha '\n', você certamente já usou esse caractere várias vezes no printf(). Então quando você aperta E e depois Enter você coloca 2 caracteres na entrada 'E' e '\n', mas os scanfs no seu programa estão esperando capturar caracteres (%c), e o caractere nova linha é um caractere, então o primeiro scanf armazenaria o caractere 'E' na variável l, e o scanf seguinte guardará o caractere '\n' na variável p, que quando combinado com erro do ; no IF gerou aquele resultado do seu programa original. A diferença dos seus programas anteriores é que provavelmente você não estava lendo caracteres no scanf, mas sim inteiros ou números com ponto flutuante (float), e apesar do caractere nova linha ainda estar lá sobrando na entrada, ele era ignorado pois os scanfs procurariam apenas números, não qualquer caractere. Quanto a sua pergunta: Aqui: int total=0; while(frase2[total] != '\0'){ total++; } Você começa a contagem em 0, e o while continua procurando até achar o caractere nulo '\0' que é o caractere que indica o fim da string.Pois em C toda string termina no caractere nulo (portanto um vetor de caracteres de comprimento 50 só pode armazenar uma string de até 49 caracteres não nulos, pois nesse caso a última posição do vetor deverá armazenar o caractere nulo). E no final terá o comprimento da string armazenado na variável total. Entretanto aqui: int e=0; for(d=0;d<50;d++){ if(frase2[d]!='\0'){ e++; } } d vai de 0 até 50, sempre indo até a última posição do vetor. Vamos supor que você declarou o vetor "char frase2[50]", o que significa que você alocou memória para armazenar os dados desse vetor, mas lá nesse espaço da memória já tinha alguma informação já que foi usada por algum outro programa anteriormente, e agora é nada mais que lixo. Você então usa um scanf para armazenar uma frase nesse vetor, por exemplo "abcde", então as 6 primeiras posições do vetor serão ocupadas por essas 5 letras mais o caractere nulo '\0', mas observe que o restante do vetor não foi alterado, ainda contém qualquer bobeira que já estava lá. Seu programa vai sair contando todos os caracteres no vetor inteiro que são diferentes de '\0', contando até qualquer coisa que está armazenada lá em cada um do resto das posições do vetor como sendo um caractere (dependendo pode até coincidentemente ter algum que tá com um 0 lá e não será contado). Logo, o resultado muito provavelmente dará errado. O modo correto de fazer o mesmo que o while no primeiro código usando for seria: int e; for(e=0; frase2[e]!='\0'; e++); ou para usar as mesmas variáveis: int total; for(total=0; frase2[total] != '\0'; total++);
×
×
  • Criar Novo...