Ir ao conteúdo
  • Cadastre-se

V!OLADOR

Membro Pleno
  • Posts

    437
  • Cadastrado em

  • Última visita

Tudo que V!OLADOR postou

  1. Alguém muito sábio disse certa vez: "o compilador tem sempre razão".
  2. Certeza que fez? aposto que deixou escapar algo daquilo que eu disse.
  3. Bom, veja que o contador não tá sendo atualizado dentro do bloco do if, como você gostaria. Então, o primeiro a fazer é usar { e } pra especificar um escopo no qual você faz a troca e atualiza o contador: if (arr[j] > arr[j+1]) { swap(&arr[j], &arr[j+1]); counter++; } Segundo, ao retornar pra função main(), você tá imprimindo um contador não inicializado e, pior, que não recebeu uma copia do resultado guardado pelo contador interno da função bubleSort(). Então, na main() certifique-se de que int counter = bubbleSort(arr, n);
  4. Cheirinho de um contador ou não inicializado com zero no inicio da função ou sendo manipulado em mais de um lugar além da função em si. Faça um contador local que apenas exista dentro da função e seja sempre inicializado com zero. Se ainda assim o erro persistir, certifique-se de que tá atualizando o contador no local correto dentro da função. Isso exige que você entenda o algoritmo.
  5. Ué, você conseguiu uma versão que faz uma medida mais difícil (tempo) e não consegue adaptar pro caso mais simples? Fica uma impressão de que copiou e colou um código de algum lugar mas não o entende. Ao entrar na função, declara um contador devidamente zerado: uint32_t counter = 0; Identifica onde a troca é feita e ali, imediatamente após, atualiza o contador: ++counter; Quando a função terminar, retorna o contador pro driver do benchmark: return counter; Isso vai requerer adaptar a interface da função também, caso ela tenha sido escrita por outra pessoa. Não pergunte onde a troca ocorre, você deve ser capaz de identificar isso sozinha, faz parte do exercício.
  6. Você tá absolutamente certo. Mas interagir com a GPU através da API do driver (OpenGL, Vulkan, DirectX etc.) é um mundo em si. Até mesmo em termos da mais simples delas, OpenGL no caso. Além do mais, GPUs são dispositivos que funcionam em paralelo, daí entra toda uma questão de paralelismo, sincronização com a CPU, shaders, rasterização etc. Creio que é muito pra quem tá apenas começando. Talvez, seja mais prático pro iniciante fazer apenas um clone de um jogo clássico, tipo Pong ou Asteroids, renderizando com a CPU. Existe uma tonelada de coisas pra aprender aqui relacionadas a matemática, detecção de colisão, taxa de quadros, medida de tempo, registrar eventos, etc. Daí em diante, querer fazer mais coisas e redescobrir esses monstros chamados de GPUs, será um processo natural.
  7. Eu imaginei. Creio que escrever as funções pessoalmente deva fazer parte do objetivo do exercício. Então, antes de falar de gráficos e benchmarks sua primeira tarefa é implementar os três algoritmos e testá-los. Felizmente, eles são bem simples e há uma zilhão de informações na internet. Aqui mesmo no fórum você vai encontrar inúmeros tópicos a respeito porque a gente gosta de reinventar a roda todo dia. Se você nunca usou um algoritmo desses, recomendo muito escrevê-lo pessoalmente. Não custa nada e é muito importante pro seu próprio aprendizado. Além do mais você vai ter propriedade na hora de interpretar os resultados do benchmark.
  8. Apesar que, aparentemente, a pergunta foi sobre como fazer gráficos, apenas por descargo de consciência, pergunta: você já tem todos os códigos necessários pra fazer os benchmarks? Ou seja, a dúvida é realmente apenas sobre como plotar um gráfico? Assumindo que a resposta seja "não tenho e a dúvida é como coletar os dados", e pra poupar tempo, algumas dicas: 1) Escreva os três algoritmos (buble, insert e selection) caso uma implementação especifica não tenha sido fornecida. Estes serão os kernels do teste. 2) Implemente um programa driver (com uma função main) pra cada kernel. Esse programa vai ser responsável por um loop principal incrementando o tamanho do vetor de teste, de 500 em 500. 3) Pra cada passo do loop, crie um vetor e preencha os elementos. No caso especifico do vetor desordenado você pode utilizar números aleatórios produzidos com as funções srand() e rand() da biblioteca stdlib.h. 4) Com o vetor devidamente preenchido, chame o kernel do teste. 5) Quando o teste terminar, escreva num arquivo de texto o tamanho do vetor e a quantidade que você tá monitorando (no caso, número de atribuições). Tipo, um par x, y. 6) Destrua o vetor e siga pro próximo passo do loop, em (3). 7) Quando terminar todo o teste, em todos os tamanhos, execute o driver mais algumas vezes (três, por exemplo). Os resultados podem ter mais significado estatístico coletando dados de três ou mais execuções. E o resultado final pode ser uma média de todas as execuções. Possivelmente, apenas relevante pro caso desordenado. Basta repetir todo o processo pra cada tipo de ordenação. Dica: evite fazer todos os testes no mesmo driver pra que um bug qualquer e inesperado de um teste não contamine o próximo. Três testes? três programas independentes. Pronto, dados coletados? basta fazer uns gráficos legais daqueles que a gente aprende no jardim de infância .
  9. Se tiver afiado no inglês, recomendo muito o canal do javidx9. Lá você vai encontrar uma série de videos-tutoriais mostrando o passo-a-passo pra renderizar gráficos em tempo real usando apenas a CPU. Ele foca principalmente no básico, ou seja, a matemática necessária e os rudimentos de C++ (quase C). Exatamente o que você precisa. Mas antes de pensar em criar jogos, no sentido geral do termo, tente dominar o básico sobre renderizar imagens na tela de forma rudimentar (sem uma GPU, sem 3D), interagir com ela em tempo real, aplicar proporções pra criar a ilusão de profundidade, ilusão de movimento etc. Apenas nesses aspectos já há bastante material de estudo antes mesmo de pensar em fazer o primeiro jogo. Vou anexar abaixo um dos videos do javidx9 sobre desenhar triângulos e proporções. Durante os videos ele vai indicar bibliotecas e outras tantas coisas mais que você possa precisar/saber. https://www.youtube.com/watch?v=ih20l3pJoeU
  10. É verdade! Só atinei pro detalhe agora. Tenho que me educar a pousar os olhos nas perguntas das pessoas por um pouco mais de 1 mili-segundo antes de responder . Valeu, @Midori!
  11. Você pode escanear a string com um for, enquanto não esbarrar no \0 (ou seja, no final): for (int n = 0; string[n] != '\0'; ++n) Ou, usar a função strlen() da biblioteca string.h: size_t total = strlen(string);
  12. Vai ser mais prático se você usar std::vector pra listaDeProdutos: // class portfolio std::vector<produto> listaDeProdutos; Agora você não vai mais precisar de quantidadeDeProdutos, porque basta checar o tamanho de listaDeProdutos em tempo real: quantidade = listaDeProdutos.std::vector<produto>::size(); E também não vai precisar de capacidadeMaxima porque o std::vector cuida disso pra você. Pra adicionar um novo produto sem precisar reajustar a lista pessoalmente, você pode usar o push_back() de std::vector: // portfolio::inserirNovoProduto() listaDeProdutos.std::vector<produto>::push_back(umProduto); Também não vai mais precisar de portfolio::redimensionarCapacidade().
  13. Aaaah, muito mais claro agora. Parece simples. Assim como na minha primeira resposta, vamos usar float pra representar números reais com baixa precisão (mais ou menos entre 4 e 6 dígitos). Caso o sensor forneça números mais precisos (mais de 8 dígitos) e você precise dessa precisão na porcentagem, utilize double. Bom, vou utilizar d pra representar a distância recebida do sensor e definir duas constantes, d_min e d_max, com os respectivos mínimos e máximos da escala, seguindo a descrição que você deu acima: float d = 0.0f; const float d_max = 30.0f; const float d_min = 220.0f; Em seguida, você disse que não tem interesse em distâncias menores do que 30 cm. Então, você poderia descartar todos os valores de d menores que d_max, por exemplo: if (d < d_max) d = d_max; A linha acima vai garantir d = 30 sempre que o sensor fizer uma medida abaixo disso. Você pode então, opcionalmente, decidir mostrar essa informação ou não. Quando o valor de d for maior que 30, e menor que 220, você aplica aquela fórmula pra converter o sinal do sensor pra uma escala entre 0 e 1 (100%): d = (-d_min + d)/190.0f; Agora d está normalizado em [-1, 0] porque, no teu problema esquisito, a escala tá invertida. Basta então pegar o valor absoluto de d: d = fabs(d); Ou, mais facilmente, apenas multiplicando d por -1 : d = -d; Agora o resultado tá normalizado em [0, 1]. Você pode multiplicá-lo por 100.0f pra ficar com mais cara de porcentagem. Veja se consegue resolver o problema com esses passos. Qualquer enrosco e só perguntar.
  14. Não vale a pena. Alocação dinâmica é muito custosa. É mais eficiente alocar um bom pedaço de memória no inicio e apenas dobrar esse pedaço quando tiver esgotado todo o espaço. Na hora de reduzir você apenas define o índice que referencia o "topo" da parte utilizável de maneira que os índices acima referem-se a parte da memória alocada (e pronta pra uso) mas não utilizada. Esse método previne também a fragmentação da memória que vai ocorrer com as sucessivas chamadas de malloc, realloc e free. De forma geral, essa ideia transforma o processo relativamente ineficiente de alocar, realocar e liberar memória numa simples manipulação de ponteiros, ou seja, super rápido. Na industria de games AAA, por exemplo, malloc, realloc, free, new e delete não são utilizados nas partes críticas do projeto.
  15. Hm, confuso. Me pergunto se você tá formulando o problema corretamente. Por exemplo, essa parte: contradiz essa aqui Eu tô a ler esse último trecho como "0 cm a se tornar 100%", é isso mesmo? se sim, qual o limite da escala? ou seja, 100% corresponde a 0 cm ou 10 cm? O fato é que uma escala precisa ter os limites estabelecidos e daí em diante são constantes. Em principio, não faz muito sentido que 100% (e 0%) represente metragens diferentes. Talvez eu possa ajudar se você explicar melhor. Caso não consiga com palavras, talvez uma tabela com alguns valores do sensor, com as unidades, além das respectivas porcentagens que você gostaria, e os limites, ou seja, a quantos centímetros equivale 0% e 100%.
  16. Talvez simplesmente normalizar a escala, ou seja [30, 10] --> [0, 1], com uma formulinha do tipo: float d = fabs((-30.0f + distancia)/20.0f); Opcionalmente você poderia multiplicar d por 100 também. A função fabs() retorna o valor absoluto da expressão e você precisa da biblioteca math.h pra usá-la.
  17. A resposta curta é sim. Agora, faria sentido? depende do problema. Um disco é um recurso físico e inerentemente sequencial, independente do modelo de programação utilizado ou do número de processos/threads executando ao mesmo tempo. Não há como ler duas coisas ao mesmo tempo. Num disco rígido por exemplo, ou a agulha tá num local ou noutro. Num SSD há acesso direto e virtualmente sem tempo de resposta mas ainda assim um processo físico de escritura. O sistema operacional vai tentar otimizar a tarefa utilizando algum tipo de cache e que permite uma ilusão de que vários processos/threads tão utilizando o disco em paralelo. Na pior das hipóteses, tentar escrever ao mesmo tempo vai destruir a performance do programa porque as threads vão precisar sincronizar-se numa fila. Um resultado contra intuitivo se tá tentando usar várias threads exatamente pra aumentar a velocidade do programa. Geralmente, é mais eficiente e inteligente criar um modelo de utilização. Se você for fiel ao próprio modelo, tudo vai funcionar sem problemas. Por exemplo, criar uma cache na RAM pra cada thread, guardar informações ali por enquanto e apenas transferir cada cache pro disco a posteriori sequencialmente. Vira e mexe, sempre que lidamos com largura de banda e latência, sai mais barato transferir um pedaço grande de informação uma vez do que vários pedaços pequenos. Outra ideia seria ter uma "thread-escrivã" e apenas ela seria responsável por escrever no disco. As demais mandariam informações pra escrivã e essa trata de escrever quando achar apropriado. O mesmo pra leitura e/ou ler-escrever.
  18. O que você chama de DAT seria um arquivo escrito com o formato binário? se sim, o uso depende do caso. Se você está guardando (num CD, HDD, SSD etc.) informação a ser lida posteriormente por um humano, convêm escrevê-la em formato texto por razões obvias. Se o intuito daquela informação é ser lida e/ou escrita por uma maquina, faz mais sentido escrevê-la em formato binário. Alguns formatos de dados não têm uma representação inteligível em texto, então faria ainda mais sentido nunca usar formato texto nesses casos. Por exemplo, bytecode, gif, jpeg, vídeos etc. Também tem a questão da performance. O formato texto possui muita informação redundante que faz sentido pra gente e é inútil pra maquina; por exemplo, o espaço entre palavras. Então, dados guardados em texto normalmente ocupam muito mais espaço em disco do que um formato binário. Estes também são mais rápidos pra acessar e escrever visto que não há necessidade de conversão pro formato texto.
  19. No link a seguir você vai encontrar um exemplo completo do mesmo problema: Write a program to print all permutations of a given string
  20. Aparentemente a lógica se perde porque você condiciona um caso else a um caso if externo e isso não gera o comportamento esperado. Ao invés de um if-else dentro de outro if-else, utilize um if-else-if. Ou seja, na função resultado if () { } else if () { } else if () { } /* ...as 7 possibilidades de a e b */ else { /* caso empate */ return 1; } return 0; Por sinal, nas duas funções anteriores o mesmo comportamento errático pode acontecer.
  21. Obrigado por contribuir pra minha procrastinação dominical.
  22. Sim, já eu estou assumindo que ele venha a resolver com um simples loop, sem fatores nem somatórios. Deixo a decisão da forma mais conveniente pra ele.
  23. Bom, a @Midori já resolveu perfeitamente. No caso da minha versão, eu faria algo similar a ela, ou seja criar uma função que teste se um dado valor é quadrado ou não primeiro: bool quadrado_perfeito(const int valor) { for(int i = 1; i <= valor; ++i) { if (valor == i*i) return true; } return false; } Até tomei a liberdade de roubar a interface da Midori. Dai basta usar essa função pra testar o valor dado pelo usuário e, caso seja um quadrado perfeito, você faz um novo loop testando os próximos 10 depois dele (vou usar n como um contador no exemplo abaixo, e j pro candidato a quadrado perfeito), algo como, int j = valor + 1, n = 0; while (n < 10) { // testa se j seria um quadrado perfeito usando a função, e se for incrementa o contador até chegar em 10: ++n ++j; } Você sabe criar e usar funções? ps.: eu não escrevo o exemplo completo porque acredito que seja importante que o faça por conta própria, pro aprendizado.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!