Guest Posted February 17, 2023 Share Posted February 17, 2023 2 minutes ago, DixieJoe said: Então você programa em Assembly? Legal. Veja os exemplos que mandei pro omesmo que tem rotinas em Assembly que eu comprei de um programador da Servia há muitos anos atrás. Tem os fontes e alguns exemplos. As rotinas dele voam... Chegam a 300.000.000 de conjuntos gerados e filtrados por segundo. SIm, mas Assembly para plataforma dos micro - controladores ( PIC, 8051 ), tal qual fazia com 8080, 8085, Z80, anos 80 e 90 ! mas não programa em Assembly para PC, muitos processadores diferentes, complicado portar cada caso depois darei uma olhadinha nos códigos, quem sabe, consiga entender algo Quote Link to comment Share on other sites More sharing options...
DixieJoe Posted February 17, 2023 Share Posted February 17, 2023 Maravilha, eolocos! Tentei programar algumas coisas para PIC mas apanhei muito e desisti, kkk 1 Quote Link to comment Share on other sites More sharing options...
DixieJoe Posted February 17, 2023 Share Posted February 17, 2023 Agora, DixieJoe disse: Maravilha, eolocos! Tentei programar algumas coisas para PIC mas apanhei muito e desisti, kkk Eu e meu filho fizemos algumas tentativas de dispenser de álcool gel automatico usando micro-controladores PIC (no auge da pandemia). Funcionava até bem, mas não tivemos grana para investir e fazer marketing. 1 Quote Link to comment Share on other sites More sharing options...
Guest Posted February 17, 2023 Share Posted February 17, 2023 7 minutes ago, DixieJoe said: Maravilha, eolocos! Tentei programar algumas coisas para PIC mas apanhei muito e desisti, kkk PIC só é complicado nos primeiros dias depois piora mas eu gosto de programar em Assembly, dá uns nós na cabeça, mas é muito legal porém, eu só faço isto, quando há um trabalho específico, sob encomenda, para a área médica ! efetuo todo o trabalho, desenho mecânico, elétrico, eletrônico, cálculos dos circuitos, programação e finalmente, monto um protótipo e entrego ao cliente. mas, não coloco um centavo meu no projeto, o cliente banca tudo, no final, recebo minha grana e pronto Quote Link to comment Share on other sites More sharing options...
Guest Posted February 17, 2023 Share Posted February 17, 2023 mas de volta o tópico eu não sei fazer a tal comparação entre "strings" ( da loteria ) de outra forma, então converto tudo em bits, e simplesmente varro os 2 arrays ao mesmo tempo e comparo bit a bit ! em Perl, é possível verificar de modo fácil, se uma dezena está dentro de um array: if ( $dezena ~ @array ) { $counter++ } Quote Link to comment Share on other sites More sharing options...
Guest Posted February 17, 2023 Share Posted February 17, 2023 (edited) 4 minutes ago, Eolocos said: mas de volta o tópico eu não sei fazer a tal comparação entre "strings" ( da loteria ) de outra forma, então converto tudo em bits, e simplesmente varro os 2 arrays ao mesmo tempo e comparo bit a bit ! em Perl, é possível verificar de modo fácil, se uma dezena está dentro de um array: if ( $dezena ~ @array ) { $counter++ } assim, se quiser usar o Diagrama de Venn, que o @sorel gosta tanto, fica mais fácil: if ( $dezena ~ @array1 && $dezena ~ @array2 ) { push @array3, $dezena } Edited February 17, 2023 by Eolocos o burrinho aqui errou o nome do diagrama ! Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 17, 2023 Author Share Posted February 17, 2023 2 minutos atrás, Eolocos disse: assim, se quiser usar o Diagrama de Venn, que o @sorel gosta tanto, fica mais fácil: if ( $dezena ~ @array1 && $dezena ~ @array2 ) { push @array3, $dezena } troço complicado, quando sorel aparecer vc se vira com ele tá, mas se vc entende isso deve ser facil entender o sorel mas no caso acho que isso faz um força bruta testa dentro de um loop em vba eu faço algo como for c=1 to final if combinação(bit(c)) then cont=cont+1 combinação seria uma matriz com o tamanho da loteria com cada dezena setada em sua posição mais ou menos isso mas procesadores tem instruções proprias de comparar e contar bit em um intenge eu uso isso para transformar a combinação em um inteiro Function combin_para_inteiro(matriz1 As Range) As Long Dim i As Long Dim num As Long arr1 = matriz1.Value2 For i = 1 To UBound(arr1, 2) num = num + 2 ^ (arr1(1, i) - 1) Next i combin_para_inteiro = num End Function 1 1 Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 17, 2023 Author Share Posted February 17, 2023 @DixieJoepo vc falou que nao gostou do gpt eu pedi a ele para converter um assembly daquele em c , pode até pedi uma explicação da funcionalidade "só nao sei se está falando a verdade kkkk" ; function LotIndex( Lot:LotMap ): LongInt; far; LotIndex PROC FAR Lot:DWORD PUBLIC LotIndex xor eax, eax ; Index := 0 les si, Triangle mov ecx, Lot @@41: jecxz @@44 @@42: shr ecx, 1 ; Inc(x) jc @@43 ; if x in ... add si, 4 ; Inc(j) jmp @@42 @@43: add eax, es:[si] ; Index := Index + ... add si, 128 ; Inc(i) jmp @@41 @@44: mov edx, eax shr edx, 16 ret LotIndex ENDP Citar Sim, é possível converter o código assembly em uma função equivalente em C. A conversão depende da arquitetura do processador em que o código assembly será executado. Abaixo, segue um exemplo de como a função em assembly poderia ser escrita em C para a arquitetura x86: ong LotIndex(long Lot) { long Index = 0; char* Triangle = (char*)0x12345678; // endereço da variável Triangle while (Lot != 0) { if (Lot & 1) { Triangle += 4; } else { Index += *((int*)Triangle); Triangle += 128; } Lot >>= 1; } return (Index >> 16); } Neste exemplo, a função em C tem a mesma assinatura da função em assembly, com um parâmetro do tipo long e um valor de retorno do tipo long. A função usa uma variável Index para acumular o valor da soma e um ponteiro Triangle para apontar para a variável correspondente em memória. O endereço da variável Triangle foi definido como 0x12345678 como exemplo. É necessário alterar esse valor para o endereço correto da variável na memória. A lógica do loop em C é equivalente à do loop em assembly. A verificação de paridade de Lot é realizada usando o operador & para testar se o bit menos significativo é 1. A operação de deslocamento é realizada usando o operador >>. As operações de adição e incremento de ponteiro são realizadas usando os operadores + e +=. O tipo do ponteiro Triangle foi definido como char*, mas pode ser alterado para o tipo correto, dependendo da arquitetura e do tipo de dados armazenados na variável. Por fim, o valor retornado é obtido a partir do valor acumulado em Index e deslocado 16 bits para a direita, para obter a metade superior do valor. 1 Quote Link to comment Share on other sites More sharing options...
DixieJoe Posted February 18, 2023 Share Posted February 18, 2023 A questão é saber se está correto e se funciona! 1 Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 18, 2023 Author Share Posted February 18, 2023 1 minuto atrás, DixieJoe disse: A questão é saber se está correto e se funciona! a ia deu uma descrição completa antes disso , dependendo de como se faz a pergunta e das informações que se apresenta ela até que é bem responsiva tipo aquele gerador de combinações assembly para pb ele deu uma descrição do que faz o problema é que pedir para gfazer em C e ela fez em swift kkkk, eu nem tinha reparado até ler o nome 1 Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 18, 2023 Author Share Posted February 18, 2023 16 minutos atrás, Omesmo disse: tipo aquele gerador de combinações assembly para pb ele deu uma descrição do que faz o problema é que pedir para gfazer em C e ela fez em swift kkkk, eu nem tinha reparado até ler o nome no sufoco consegui fazer ele gerar em C as vezes é necessário reiniciar o chat ou criar um do zero, senao ele se confunde nas coisas que ele mesmo disse Citar consegue montar o mesmo codigo dentro da linguagem "C" ? Sim, é possível traduzir o código do PowerBASIC para C. No entanto, é importante lembrar que o código original contém algumas variáveis e declarações globais, e que essas variáveis precisariam ser replicadas de alguma forma em C. Abaixo está uma tradução aproximada do código do PowerBASIC para C. Esta tradução é apenas um ponto de partida e pode precisar ser ajustada para atender às necessidades específicas do projeto: #include <stdio.h> #include <stdlib.h> #define MAX_COMBS 51000000 long lotto_combs[MAX_COMBS * 7]; long *ptr2_lotto_combs; long number_of_combinations = 0; long *ptr2_number_of_combinations; long full_number = 0; long *ptr2_full_number; void generate_combinations() { asm { push ebx push ecx push edx push esi push edi mov esi, ptr2_lotto_combs mov edi, ptr2_number_of_combinations mov ebx, ptr2_full_number mov edx, 1 mov eax, [ebx] mov ecx, [eax] shl ecx, 1 mov [edi], 0 startloop: mov [esi+edx-1], 1 call next_combination cmp [eax], 0 jne add_combination jmp endloop add_combination: add [edi], 1 endloop: cmp edx, ecx jne startloop pop edi pop esi pop edx pop ecx pop ebx } } void next_combination() { asm { push ebx push ecx push edx push esi mov esi, ptr2_lotto_combs mov ebx, ptr2_full_number mov edx, 7 loop1: dec edx mov ecx, [esi+edx-1] cmp ecx, [ebx] je loop1 mov [esi+edx-1], ecx+1 mov eax, edx mul eax sub eax, edx mov edx, 6 div edx mov ecx, [esi+eax*6-6] mov ebx, [esi+edx*6-6] cmp ecx, ebx jb loop1 pop esi pop edx pop ecx pop ebx } } int main() { ptr2_lotto_combs = &lotto_combs[0]; ptr2_number_of_combinations = &number_of_combinations; ptr2_full_number = &full_number; // Aqui é necessário definir o valor de full_number antes de chamar a função generate_combinations() generate_combinations(); // O resultado das combinações geradas pode ser acessado através de lotto_combs[] usando a fórmula lotto_combs[(i-1)*6+j] } #include <stdio.h> // Define global variables #define MAX_COMBS 51000000 unsigned char lotto_combs[MAX_COMBS * 7]; unsigned char *ptr2_lotto_combs = &lotto_combs[0]; long number_of_combinations = 0; long *ptr2_number_of_combinations = &number_of_combinations; long full_number = 0; long *ptr2_full_number = &full_number; void generate_combinations() { __asm { mov ebx, 1 // i = 1 mov ecx, [ptr2_lotto_combs] mov eax, [ptr2_number_of_combinations] mov edx, [ptr2_full_number] jmp start loop_i: inc ebx // i++ cmp ebx, [eax] // if i > number_of_combinations, exit loop jg end_loop start: mov esi, ebx mov edi, ecx loop_j: mov [edi], esi inc edi shr esi, 8 cmp edi, ecx + 6 // if j == 6, exit loop je end_j_loop jmp loop_j end_j_loop: inc [eax] // increment number_of_combinations add ecx, 7 // increment lotto_combs pointer jmp loop_i end_loop: } } int main() { ptr2_lotto_combs = &lotto_combs[0]; ptr2_number_of_combinations = &number_of_combinations; ptr2_full_number = &full_number; full_number = 49; // set full_number to 49 (total number in pool) generate_combinations(); // Test access to combinations printf("Combination 1, number 1: %d\n", lotto_combs[0] * 6 + 0); printf("Combination 1, number 2: %d\n", lotto_combs[0] * 6 + 1); printf("Combination 1, number 3: %d\n", lotto_combs[0] * 6 + 2); printf("Combination 1, number 4: %d\n", lotto_combs[0] * 6 + 3); printf("Combination 1, number 5: %d\n", lotto_combs[0] * 6 + 4); printf("Combination 1, number 6: %d\n", lotto_combs[0] * 6 + 5); printf("Combination 2, number 1: %d\n", lotto_combs[7] * 6 + 0); printf("Combination 2, number 2: %d\n", lotto_combs[7] * 6 + 1); printf("Combination 2, number 3: %d\n", lotto_combs[7] * 6 + 2); printf("Combination 2, number 4: %d\n", lotto_combs[7] * 6 + 3); printf("Combination 2, number 5: %d\n", lotto_combs[7] * 6 + 4); printf("Combination 2, number 6: %d\n", lotto_combs[7] * 6 + 5); return 0; } Note that the generated combinations 1 Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 18, 2023 Author Share Posted February 18, 2023 32767 49151 81919 147455 278527 540671 1064959 2113535 4210687 8404991 16793599 57343 90111 155647 286719 548863 1073151 2121727 4218879 8413183 16801791 106495 172031 303103 565247 1089535 2138111 4235263 8429567 16818175 204799 335871 598015 1122303 2170879 4268031 8462335 16850943 401407 663551 1187839 2236415 4333567 8527871 16916479 794623 1318911 2367487 4464639 8658943 17047551 1581055 2629631 4726783 8921087 17309695 3153919 5251071 9445375 17833983 This sequence of numbers appears to be a pattern of values that increase by multiplying the previous value by 1.5 and then adding 1. Here's the first few numbers in the sequence with this calculation: 32767 32767 * 1.5 + 1 = 49151 49151 * 1.5 + 1 = 81919 81919 * 1.5 + 1 = 147455 147455 * 1.5 + 1 = 278527 278527 * 1.5 + 1 = 540671 540671 * 1.5 + 1 = 1064959 1064959 * 1.5 + 1 = 2113535 2113535 * 1.5 + 1 = 4210687 4210687 * 1.5 + 1 = 8404991 8404991 * 1.5 + 1 = 16793599 kkk esse gpt as vezes tem preguiça 1 Quote Link to comment Share on other sites More sharing options...
Guest Posted February 18, 2023 Share Posted February 18, 2023 12 hours ago, Omesmo said: troço complicado, quando sorel aparecer vc se vira com ele tá, mas se vc entende isso deve ser facil entender o sorel mas no caso acho que isso faz um força bruta testa dentro de um loop em vba eu faço algo como for c=1 to final if combinação(bit(c)) then cont=cont+1 combinação seria uma matriz com o tamanho da loteria com cada dezena setada em sua posição mais ou menos isso mas procesadores tem instruções proprias de comparar e contar bit em um intenge eu uso isso para transformar a combinação em um inteiro Function combin_para_inteiro(matriz1 As Range) As Long Dim i As Long Dim num As Long arr1 = matriz1.Value2 For i = 1 To UBound(arr1, 2) num = num + 2 ^ (arr1(1, i) - 1) Next i combin_para_inteiro = num End Function não achei complicado não, achei até bonitinho o operador ~ simplesmente busca se a $dezena está dentro do array, não importa a posição ! se estiver dentro dos 2 arrays, então está também dentro do array3, push coloca a tal $dezena dentro do array3 mas só uso isto quando não importa onde dentro do array está quanto ao Sorel, na minha opinião, é uma pessoa muito inteligente, com mil ideias, porém, o raciocínio dele é muito rápido para mim, eu não consigo acompanhar tudo o que ele posta, e olha que já li trocentas postagens dele Quote Link to comment Share on other sites More sharing options...
Varelo Posted February 19, 2023 Share Posted February 19, 2023 @Sorel é de outro planeta!!! ele está aqui tentando replicar o conhecimento mas como nosso planeta está ainda em evolução agente não consegue acompanhá-lo. kkk @Eolocos Entender de Assembly é pra poucos. Quando mexia com gps tentei aprender pra quebrar software mas é muito difícil...fiquei 03 meses debruçado lendo e praticando diariamente (quase perco a mulher, ela pensava que eu tinha outra, só dava bola pro notebook...kkk)...desisti...mas até hoje a "Ida Pro" me perturba nos meus sonhos. “Quem conhece os outros é inteligente. Quem conhece a si mesmo é iluminado. Quem vence os outros é forte. Quem vence a si mesmo é invencível.” Lao Tsé \[,,]/ Quote Link to comment Share on other sites More sharing options...
rockcavera Posted February 19, 2023 Share Posted February 19, 2023 Em 17/02/2023 em 12:25, Omesmo disse: algum programador já usou contagem de bits em C para conferencia em loterias? quais métodos implementaram? é bom na velocidade ou nao é coisa de outro mundo? vale a pena implementar? @Jimmy seria bom mudar o nome mudar o nome dessa seção para "programas & programação para loterias, assim atenderia tbm a implementação de codigos Olá, @Omesmo Eu uso contagem de bits para programas de loteria. É a forma mais rápida para se trabalhar com poucas operações de máquina em loterias, o que torna o programa bem mais rápido. A minha experiência em si não é com C, tendo em vista que hoje em dia não é considerado uma linguagem "moderna", mas, sim, com Nim, que compila para C. Ou seja, no final das contas eu uso C só que com uma camada de abstração de Nim. Vamos lá. Há alguns anos eu fiz 10 implementações de countbits diferentes. Implementação 01: conta os bits por subtração em um loop while. Implementação 02: conta os bits por deslocamento Implementação 03: "Counting bits set, in parallel" (contagem de bits definidos, em paralelo) => https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel Implementação 04: Conta os bits usando uma tabela de consulta de 8 bits usando um while loop até cobrir todos os bits Implementação 05: Conta os bits usando uma tabela de consulta de 8 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop Implementação 06: Conta os bits usando uma tabela de consulta de 8 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop (diferença quase nula da implementação anterior) Implementação 07: Conta os bits usando uma tabela de consulta de 16 bits usando um while loop até cobrir todos os bits Implementação 08: Conta os bits usando uma tabela de consulta de 16 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop Implementação 09: Conta os bits usando uma tabela de consulta de 16 bits fazendo a soma aninhada de acordo com a quantidade de bits, sem precisar de um while loop (diferença quase nula da implementação anterior) Implementação 10: Conta os bits usando a instrução de processador POPCNT Depois de fazer as implementações, resolvi construir um pequeno benchmark para descobrir qual se saia melhor. Abaixo mostro os resultados: Fazendo uma única operação de contagem: Spoiler =countbits01 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 144 MedDeltaT: 144 MinT: 144 MaxT: 144 zOut: 20 =countbits02 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 160 MedDeltaT: 160 MinT: 160 MaxT: 160 zOut: 20 =countbits03 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 44 MedDeltaT: 44 MinT: 44 MaxT: 44 zOut: 20 =countbits04 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 376 MedDeltaT: 376 MinT: 376 MaxT: 376 zOut: 20 =countbits05 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 376 MedDeltaT: 376 MinT: 376 MaxT: 376 zOut: 20 =countbits06 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 392 MedDeltaT: 392 MinT: 392 MaxT: 392 zOut: 20 =countbits07 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 648 MedDeltaT: 648 MinT: 648 MaxT: 648 zOut: 20 =countbits08 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 580 MedDeltaT: 580 MinT: 580 MaxT: 580 zOut: 20 =countbits09 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 596 MedDeltaT: 596 MinT: 596 MaxT: 596 zOut: 20 =countbits10 1866120613 1= CpuTime: 0.0 Times: 1 SumDeltaT: 40 MedDeltaT: 40 MinT: 40 MaxT: 40 zOut: 20 Fazendo 100 operações de contagem: Spoiler =countbits01 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 7416 MedDeltaT: 74 MinT: 72 MaxT: 148 zOut: 20 =countbits02 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 9992 MedDeltaT: 99 MinT: 96 MaxT: 160 zOut: 20 =countbits03 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 4580 MedDeltaT: 45 MinT: 44 MaxT: 48 zOut: 20 =countbits04 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 5436 MedDeltaT: 54 MinT: 48 MaxT: 404 zOut: 20 =countbits05 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 6760 MedDeltaT: 67 MinT: 64 MaxT: 424 zOut: 20 =countbits06 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 6648 MedDeltaT: 66 MinT: 60 MaxT: 404 zOut: 20 =countbits07 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 6128 MedDeltaT: 61 MinT: 56 MaxT: 584 zOut: 20 =countbits08 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 6620 MedDeltaT: 66 MinT: 60 MaxT: 616 zOut: 20 =countbits09 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 6724 MedDeltaT: 67 MinT: 60 MaxT: 684 zOut: 20 =countbits10 1866120613 100= CpuTime: 0.0 Times: 100 SumDeltaT: 3840 MedDeltaT: 38 MinT: 36 MaxT: 40 zOut: 20 Entendendo os resultados: countbitsXX N V Onde: XX é o número da implementação N é o número que irá contar os bits V é a quantidade de vezes que irá contar os bits de N CpuTime = tempo gasto pela CPU para executar o processo atual em segundos Times = V, ou seja, quantidade de vezes que irá contar os bits SumDeltaT = soma de de ticks de CPU gastos para executar o processo MedDeltaT = média de ticks de CPU gasto para cada execução de contagem (SumDeltaT div Times) MinT = menor ticks de CPU registrado em uma única contagem de bits MaxT = maior ticks de CPU registrado em uma única contagem de bits zOut = resultado, ou seja, quantos bits definidos possui o número N Diante essa análise, pode-se classificar às duas melhores implementações, que são a 10 e a 03. O melhor dessas implementações, que elas são de tempo constante, ou seja, o tempo gasto não muda se tiver mais ou menos bits definidos. Já a implementação 01 e 02 não são de tempo constantes, pois pode ser mais rápida se tiver um único bit definido e mais lerda se tiver 32 bits definidos. Observações: 1) Interessante é do teste que executa mais vezes a mesma contagem. É possível ver que o CPU, de forma inteligente, já começa a usar o cache e executar a tarefa de forma mais rápida se comparar com o benchmark que executa uma única vez a contagem. 2) Os benchmarks não são feitos a frio, pois uso um "aquecimento" de CPU utilizando operações de ponto flutuante por, aproximadamente, 1 segundo antes de começar de fato a medição das operações do benchmark. 3) Meu processador é um mobile, que possui turbo boost. Para realizar os benchmarks eu travo o clock dele na frequência base de 2.8ghz e não deixo ele fazer o turbo boost. 4) As desvantagens de usar tabelas de consultas de 8 bits são de ocupar 256 bytes de memória ram para pré-alocar a tabela. Já a tabela de consulta de 16 bits o número de bytes sobe para 65535 (65KB). Para computadores atuais isso é insignificante. 5) A instrução POPCNT foi implementada pela Intel na microarquitetura Nehalem, de 2008. Já a AMD implementou na microarquitetura K10 (Barcelona), de 2007 [1] 3 Quote Link to comment Share on other sites More sharing options...
DixieJoe Posted February 19, 2023 Share Posted February 19, 2023 rockavera Obrigado pelas explicações! Essa contagem do item 03 (counting in parallel), eu tinha visto há algum tempo. Mas como é em C, eu acabei "ficando com medo" e abandonei. Já sua versão de POPCNT deve depender do processador de sua máquina, correto? Supondo que minha máquina (usa um Intel i5 antigo..., acredita ser possível uar essa função para contar valores que estejam em um bitstring com até 100 bits (para Lotomania, por exemplo). Ou 80 para Quina? Alguma dica de como usar? Quero dizer, como "quebrar" o bitString em Integers de 32 bits ou 64 bits e contar separadamente e depois somar... Confesso que estou totalmente perdido quanto a como fazer algo parecido. Agradeço sua disposição em me ajudar a entender isso, por favor. 3 Quote Link to comment Share on other sites More sharing options...
rockcavera Posted February 19, 2023 Share Posted February 19, 2023 36 minutos atrás, DixieJoe disse: Essa contagem do item 03 (counting in parallel), eu tinha visto há algum tempo. Mas como é em C, eu acabei "ficando com medo" e abandonei. @DixieJoe não é difícil traduzir o código de contagem paralela para outras linguagens, tendo em vista que só usa operações de bit (and), operações de deslocamento (shift right) e operações matemáticas (adição, multiplicação e subtração). 36 minutos atrás, DixieJoe disse: Já sua versão de POPCNT deve depender do processador de sua máquina, correto? Estava tomando café-da-tarde e lembrei que esqueci de botar nas observações sobre a instrução POPCNT. A intel implementou na microarquitetura Nehalem, de 2008. Já a AMD implementou na microarquitetura K10 (Barcelona), de 2007. [1] Não é difícil descobrir se seu processador suporta ou não POPCNT, sendo possível fazer isso em tempo de execução e caso não suporte, basta definir para usar outra forma que seja mais portável, igual a contagem em paralelo. Alguns compiladores C até trazem builtins para você determinar isso em tempo de execução. Caso não tenha, a forma mais simples é consultar o retorno de uma instrução CPUID, que praticamente toda linguagem possui, ou em pacote ou como extensão de linguagem. 36 minutos atrás, DixieJoe disse: Supondo que minha máquina (usa um Intel i5 antigo..., acredita ser possível uar essa função para contar valores que estejam em um bitstring com até 100 bits (para Lotomania, por exemplo). Ou 80 para Quina? Alguma dica de como usar? Quero dizer, como "quebrar" o bitString em Integers de 32 bits ou 64 bits e contar separadamente e depois somar... Confesso que estou totalmente perdido quanto a como fazer algo parecido. Vamos lá, para um computador amd64 (ou seja, 64 bits) será possível contar até 64 bits por vez com POPCNT. Então, para 100bits, você terá que usar 2 instruções POPCNT. O mesmo acontece para 80. Agora a forma de quebrar os bits, depende de como está implementado essa linguiça de bits. Por exemplo, em computadores de 32 bits quando se precisa usar 64 bits, você usa dois inteiros de 32 bits para fazer um de 64 bits. Então, para quebrar 64 bits em duas partes de 32 bits basta usar operador AND com uma máscara de bits e deslocamentos. Exemplo o número 9223372043297226750 (precisa de 64 bits). A representação em bits é: 1000000000000000000000000000000101111111111111111111111111111110. A parte superior é representada por esses 32 bits: 10000000000000000000000000000001 A parte inferior por esses: 01111111111111111111111111111110 Exemplo em C : #include <stdio.h> int main() { unsigned long long int a = 9223372043297226750ULL; unsigned long int low = a & 0xFFFFFFFFULL; unsigned long int high = a >> 32; printf("%llu\n", a); printf("Low: %lu\n", low); printf("High: %lu\n", high); return 0; } Exemplo em Nim: let a = 9223372043297226750'u64 lo = uint32(a and 0xFFFFFFFF'u64) hi = uint32(a shr 32) echo a echo "low: ", lo echo "high: ", hi Ambas as implementações irão imprimir: 9223372043297226750 low: 2147483646 high: 2147483649 Claro que cada linguagem tem suas especificidades. 3 Quote Link to comment Share on other sites More sharing options...
DixieJoe Posted February 19, 2023 Share Posted February 19, 2023 Obrigado pela aula, rockavera! Vou ter que fazer minha lição de casa. Mas a luz você deu com maestria. 3 Quote Link to comment Share on other sites More sharing options...
rockcavera Posted February 19, 2023 Share Posted February 19, 2023 5 minutos atrás, DixieJoe disse: Obrigado pela aula, rockavera! Vou ter que fazer minha lição de casa. Mas a luz você deu com maestria. Precisando de ajuda, só informar a linguagem que eu tento te ajudar. Abraço 2 Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 19, 2023 Author Share Posted February 19, 2023 2 horas atrás, rockcavera disse: A minha experiência em si não é com C, tendo em vista que hoje em dia não é considerado uma linguagem "moderna", mas, sim, com Nim, que compila para C. Ou seja, no final das contas eu uso C só que com uma camada de abstração de Nim. em comparação o ruim do c é que nao tem um coletor de lixo e tudo tem que ser feito manualmente no geral a maiorias das linguagens modernas seguiram o C o rum para mim é a estrutura e operadores (){}; :: && ... claro que com o tempo e uso se acostuma , mas merds pq fizeram assim, seria tão dificil fazer um compilador que usasse uma estrutura mais "humana" igual o basic que usa operadores usados igual na matemática? por isso o basic é tão facil de se pegar, é pq já aprendemos parte no colegio mesmo e nem é em programação, fora que acompanhar a estrutura de codigos mais complexos é mais facil ainda mais com loops e ifs alinhados sobre o POPCNT, acho que tem a partir do intel i de primeira geração no sse4.2 e acho que trabalha com 128 bit que de qualquer forma tem que ser dividido numa matriz ao meu ver se for transformar uma matriz de dezenas em um inteiro acho que valeria mais a pena já dividir na conversão de 1 a 32, inteiro A de 33 a 64 = valor -32 , inteiro B bem, eu estou só com um az1100 amd e-350 apu all in one , muito ruim, consegui até compilar usando o dev-c++ mas tenho paciência de jó nao , então vou dar um tempo no aprendizado 1 1 Quote Link to comment Share on other sites More sharing options...
Guest Posted February 20, 2023 Share Posted February 20, 2023 21 hours ago, Varelo said: @Sorel é de outro planeta!!! ele está aqui tentando replicar o conhecimento mas como nosso planeta está ainda em evolução agente não consegue acompanhá-lo. kkk @Eolocos Entender de Assembly é pra poucos. Quando mexia com gps tentei aprender pra quebrar software mas é muito difícil...fiquei 03 meses debruçado lendo e praticando diariamente (quase perco a mulher, ela pensava que eu tinha outra, só dava bola pro notebook...kkk)...desisti...mas até hoje a "Ida Pro" me perturba nos meus sonhos. “Quem conhece os outros é inteligente. Quem conhece a si mesmo é iluminado. Quem vence os outros é forte. Quem vence a si mesmo é invencível.” Lao Tsé \[,,]/ Rapaz, Assembly para quebrar software e GPS ?!!! tu não é fraco não, hein ? bom, com relação à troca esposa / programação, no teu caso, creio que fez a escolha certa. mas, eu tenho uns conhecidos, que a troca não seria vantajosa não esposas muito mais complicadas que aprender Assembly em mandarim ou cantones ! Quote Link to comment Share on other sites More sharing options...
Bruno Cintra Posted February 20, 2023 Share Posted February 20, 2023 um codigo em assembler do programa oscover que gerar v,k,t,m=b .386 .model flat, stdcall option casemap :none ; case sensitive ; ######################################################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib combinations PROTO :DWORD,:DWORD ; ######################################################################### szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM m2m MACRO M1, M2 push M2 pop M1 ENDM return MACRO arg mov eax, arg ret ENDM .code ; ########################################################################## LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD szText LmTitle,"Cover Functions" .if reason == DLL_PROCESS_ATTACH szText ATTACHPROCESS,"PROCESS_ATTACH" return TRUE ; ----------------------------- ; If error at startup, return 0 ; System will abort loading DLL ; ----------------------------- .elseif reason == DLL_PROCESS_DETACH szText DETACHPROCESS,"PROCESS_DETACH" .elseif reason == DLL_THREAD_ATTACH szText ATTACHTHREAD,"THREAD_ATTACH" .elseif reason == DLL_THREAD_DETACH szText DETACHTHREAD,"THREAD_DETACH" .endif ret LibMain Endp ; ########################################################################## ; *** Count the number of bits in DWORD bitCount proc STDCALL number:DWORD sub eax,eax mov ecx,number cmp eax,ecx je noBits bitLp: inc eax mov ebx,ecx dec ebx and ecx,ebx jne bitLp noBits: ret bitCount endp ; *** Count combinations of subsets in full set n!/k!(n-k)! combinations proc STDCALL subSet:DWORD,fullSet:DWORD sub edx,edx push edx mov eax,subSet bts edx,eax dec edx nextLp: sub ecx,ecx mov ebx,edx bitLp: inc ecx mov eax,ebx dec eax and ebx,eax jnz bitLp cmp ecx,subSet jne badCount inc DWORD PTR [esp] mov eax,edx dec eax or edx,eax badCount: inc edx mov eax,fullSet bt edx,eax jnc nextLp pop eax ret combinations endp ; *** Count how many cover sets are contained within a list of source sets ; *** ignore sets with MSb on checkCover proc STDCALL cover:DWORD,subSet:DWORD,fullSet:DWORD,setList:DWORD push edi push esi sub edx,edx push edx mov eax,subSet bts edx,eax dec edx mov esi,setList lea edi,subSet nextTestSet: sub ebx,ebx add ebx,edx jz badCount sub ecx,ecx bitLp: inc cx mov eax,ebx dec eax and ebx,eax jnz bitLp cmp cx,[edi] jge isGoodCnt badCount: bt ecx,16 jc isBadCover nextComb: inc edx mov ebx,fullSet bt edx,ebx jnc nextTestSet jmp finished isGoodCnt: bts ecx,16 jc isCoverTest jne nextComb isBadCover: lea edi,cover testSetLp: add ebx,[esi] jz endTestSet add esi,4 bt ebx,31 jnc notFlagged sub ebx,ebx notFlagged: and ebx,edx jz testSetLp sub cx,cx jmp bitLp isCoverTest: inc DWORD PTR [esp] mov eax,edx dec eax or edx,eax endTestSet: mov esi,setList sub ecx,ecx lea edi,subSet jmp nextComb finished: pop eax pop esi pop edi ret checkCover endp ; *** calculate how many unique combinations are covered by each set in list rankSets proc STDCALL cover:DWORD,subSet:DWORD,fullSet:DWORD,setList:DWORD LOCAL setAddr:DWORD push edi push esi mov esi,setList sub eax,eax notZero: add eax,4 cmp DWORD PTR [esi+eax],0 jne notZero invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT, eax push eax mov eax,subSet sub edx,edx bts edx,eax dec edx nextCheck: lea edi,subSet mov ebx,edx sub ecx,ecx mov setAddr,ecx bitLp: inc cx mov eax,ebx dec eax and ebx,eax jnz bitLp cmp cx,[edi] bts ecx,16 jge goodCount jc nextSet jmp nextComb goodCount: jnc isCover cmp ebx,setAddr jne notUnique mov setAddr,esi jmp nextSet isCover: jne nextComb lea edi,cover mov esi,setList nextSet: add ebx,[esi] je endList add esi,4 and ebx,edx je nextSet sub cx,cx jmp bitLp endList: add ebx,setAddr je notUnique sub ebx,setList add ebx,[esp] mov esi,ebx inc DWORD PTR [esi-4] notUnique: mov eax,edx dec eax or edx,eax nextComb: inc edx mov eax,fullSet bt edx,eax jnc nextCheck pop eax pop esi pop edi ret rankSets endp ; *** search for the best set to add to a set list bestSet proc STDCALL cover:DWORD,subSet:DWORD,fullSet:DWORD,setList:DWORD LOCAL condition:DWORD LOCAL workList:DWORD LOCAL coverCntr:DWORD LOCAL bestCover:DWORD LOCAL newBestSet:DWORD push edi push esi mov condition,6 sub eax,eax mov bestCover,eax invoke combinations,subSet,fullSet shl eax,4 invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT, eax push eax mov eax,setList mov workList,eax mov eax,cover stageLp: push DWORD PTR [esp] sub edx,edx bts edx,eax dec edx nextCheck: mov ebx,edx lea edi,condition and ecx,20000H jnz bitLp lea edi,subSet bitLp: inc cx mov eax,ebx dec eax and ebx,eax jnz bitLp cmp cx,[edi] bts ecx,16 jge goodCount jc noBits jmp nextComb goodCount: jnc isComb bt ecx,17 jnc isCover ; *** stage two - count a cover for this draw set inc DWORD PTR coverCntr jmp noBits isComb: jne nextComb mov esi,workList noBits: add ebx,[esi] je endSetList add esi,4 sub cx,cx and ebx,edx lea edi,cover jne bitLp jmp noBits endSetList: bt ecx,17 jnc incListAddr mov eax,coverCntr mov coverCntr,ebx cmp eax,bestCover jle isCover mov bestCover,eax mov newBestSet,edx jmp isCover incListAddr: mov esi,[esp] mov [esi],edx add DWORD PTR [esp],4 isCover: mov eax,edx dec eax or edx,eax nextComb: inc edx mov eax,fullSet bt edx,eax jnc nextCheck ; *** move to stage two - find best set of six numbers to cover all uncovered combinations pop eax mov eax,[esp] mov workList,eax sub ebx,ebx mov coverCntr,ebx mov eax,condition bts ecx,17 jnc stageLp pop eax invoke GlobalFree,eax mov eax,newBestSet pop esi pop edi ret bestSet endp ; ########################################################################## End LibMain 1 Quote Link to comment Share on other sites More sharing options...
rockcavera Posted February 21, 2023 Share Posted February 21, 2023 @Bruno Cintraaté hj não aprendeu a usar o editor do fórum para colocar código? Só lembrando que já tentei te ensinar umas 2 vezes, inclusive com print. Quando se cola código fora da caixa de código, o código pode ser alterado por um encode de entities html, em linguagens que o recuo importa como escopo pode perder espaço... São vários problemas. Então fica de novo essa dica, quem sabe na próxima. Edit: comentário rabugento? Sim. Mas colar um código dessa forma pode atrasar a vida de alguém que tenta compilar isso e não funciona, devido a falta de cautela de quem não usa dos meios corretos para publicar o código. 1 Quote Link to comment Share on other sites More sharing options...
Bruno Cintra Posted February 21, 2023 Share Posted February 21, 2023 Kkkk Quote Link to comment Share on other sites More sharing options...
Omesmo Posted February 21, 2023 Author Share Posted February 21, 2023 estava vendo os codigos gerados pelo gpt e reparei nisso if (__builtin_popcount(i) == k) { // verifica se i tem exatamente k bits definidos __builtin_popcount(i) pesquisando vi que apesar de nao ser padrão do C tem compilador que incorpora funções desse tipo como o GCC para int use __builtin_popcount(n) para int longo use __builtin_popcountl(n) para long long int use __builtin_popcountll(n) o problema é que parece que precisaria fazer um para cada tipo, se fosse escolhido o tipo em tempo de execução ficaria mais lento pedi para o gpt montar um contador de bits para 100bits usando assembly numa função c #include <stdint.h> uint64_t popcnt_100bits(const void *ptr) { uint64_t count; __asm__ volatile ( "movdqu xmm0, [%[ptr]] \n" "movdqu xmm1, [%[ptr]+16] \n" "movdqu xmm2, [%[ptr]+32] \n" "movdqu xmm3, [%[ptr]+48] \n" "movdqu xmm4, [%[ptr]+64] \n" "pshufb xmm5, xmm0 \n" "pshufb xmm6, xmm1 \n" "pshufb xmm7, xmm2 \n" "pshufb xmm8, xmm3 \n" "pshufb xmm9, xmm4 \n" "popcnt %[count], xmm5 \n" "popcnt %%rdx, xmm6 \n" "add %[count], %%rdx \n" "popcnt %%rcx, xmm7 \n" "add %[count], %%rcx \n" "popcnt %%rbx, xmm8 \n" "add %[count], %%rbx \n" "popcnt %%rsi, xmm9 \n" "add %[count], %%rsi \n" : [count] "=r" (count) : [ptr] "r" (ptr) : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "memory" ); return count; } Citar Neste código, a função C popcnt_100bits chama o código em assembly que conta o número de bits definidos como 1 em um número de 100 bits. A função C declara uma variável count para armazenar o resultado do cálculo em assembly. A instrução __asm__ volatile é usada para incorporar o código assembly em uma função C. Os registradores xmm0 a xmm9 são usados para armazenar os valores dos registradores SIMD SSE, e a opção memory é usada para notificar o compilador que a função pode acessar a memória. A opção r é usada para especificar que o ponteiro ptr é passado como um registrador. A opção =r é usada para especificar que a variável count é passada como um registrador de saída. As instruções movdqu, pshufb e popcnt são as mesmas que as usadas no código em assembly que eu apresentei anteriormente. eu adoraria fazer funções em dll para usar em planilhas apesar da maioria das coisas que eu faço funcionar muito bem em vba tem uns testes meus que demora muito pelo grande numero de testes que faz 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.