Cálculo de logaritmo de um número por um terceiro método em C
Publicado por Perfil removido (última atualização em 18/05/2012)
[ Hits: 9.457 ]
Download logaritmo-metodo-c-001.c
Este é um terceiro método de cálculo de logaritmos e o curioso é que sempre são necessários os mesmos números de passos para o cálculo.
Bem diferente do que cito como métodos "A" e "B".
Não é nada inovador e é do tipo de coisa vista num curso escolar sobre a matéria.
Detalhes no código.
Não precisa de derivadas. Apenas saber raiz quadrada. O que significa que dá prá fazer com o auxílio de uma calculadora do tipo que não é científica e algumas anotações caso esta calculadora tenha restrição de memória.
Portanto a precisão e o custo computacional estão ligados diretamente ao algoritmo de raiz quadrada usado.
Ele usa o mesmo método quese usa para saber quantas casas decimais ou quantos bits tem um número.
Ao se escrever um número de binário para decimal, são usadas somas de potências de 2 e *** qualquer número é uma soma de potências não-repetidas de 2.
Como se faz mesmo? Divide-se por 2 repetidas vezes e anotam-se os restos, 0 e 1 alternados que serão os dígitos de escrita.
Por exemplo: 32 = 2 elevado à 5. São feitas 5 divisões por 2. Por acaso esse 5 é o expoente e o logaritmo.
Para 33 = 2 elevado à 5. mais 1. A diferença é que sobrou 1.
Se a parte inteira desse logaritmo de 33 base 2 é 5 e pôde ser calculada, então não existiria algo a ser feito com esse 1 que sobrou prá saber qual é o logaritmo de 33 base 2 fracionado?
A resposta é sim.
Numa divisão, divisão mesmo, quando o resto é maior que o número prá se dividir, coloca-se a vírgula e vão sendo colocados zeros quando não se consegue dividir.
Se o objetivo era o de descobrir quantos 2 existiam dentro de 33, agora esse objetivo deve ser mudado porque 2 já não é possível com o resto 1.
Agora deve-se descobrir quantas "raiz quadradas de 2" existem neste resto. Dividir o resto por sqrt(2) quantas vezes for possível, contar quantas divisões foram feitas e colocar após a vírgula colocada após o cinco.
E quando o resto for de novo menor que o teste, que é "raiz quadrada de 2", muda se de novo o teste. Muda-se para "raiz quadrada da raiz quadrada" de dois. Também chamada de a "raiz quarta".
Faz-se a mesma coisa: contam-se o número de divisões e anota-se na casa decimal seguinte à da última contagem.
O único problema é que este método depende do sistema de numeração adotado.
Esse exemplo citado acima foi para base 2. Para fazer com base 10, precisa trabalhar com "raiz décima". E agora?
Da mesma forma que inteiros são representados por somas de potências de dois, fracionários também podem ser representados.
Representados por somas de potências de 0.5 (ou 1/2).
Ficaria a sequência: 1/2, 1/4, 1/8, 1/16, 1/32...
1/2 = 0.1 binário
1/4 = 0.01 binário
1/8 = 0.001 binário
1/16 = 0.0001 binário
1/32 = 0.00001 binário
Da mesma forma que existem decimais de casas infinitas, existiriam binários de casas infinitas.
No caso do teste de divisão existiriam duas hipóteses:
"dá prá dividir" o resultado da divisão é 1
"não dá prá dividir" o resultado da divisão é 0
Sempre havendo resto.
Se fosse prá escrever em binário de baixo nível na memória, bastava deslocar uma casa tipo "x >> 1" em ponto flutuante e inverter o bit, mas parece que em C não há como e ainda não me inteirei do que poderia ser feito. Ainda.
Então o jeito é somar potências de (1/2) decimais numa variável conforme o resultado da divisão seja 0 ou 1.
O expoente da potência somada corresponde à casa fracionária binária.
Fiquem à vontade para sugestões, dúvidas ou apontar erros e simplificações.
#include <stdio.h> #include <math.h> // Algoritmo "C" // Um terceiro Método Para Logaritmos // Nao sei quem poderia ja te-lo inventado porque simplesmente ainda nao encontrei um autor descrevendo este metodo // E tambem nao sei quem o sugeriu porque ainda nao encontrei como sugestao ou descricao em nenhum livro, artigo ou site // Nem executado em papel e nem executado em maquina // Mas eh certeza que alguem ja fez e ateh melhor no ambito escolar. // Favor compilar com // gcc logaritmo-metodo-c-001.c -o logaritmo-metodo-c-001 -lm // Calcula logaritmo natural - Base "e" - nessa situacao // Pode ser mudado para a base que se quser sem esforcos // Nao diverge e nem depende de chute // O numero de passos so muda dependendo da precisao do ponto flutuante ou de quanto quer se aproximar // Essa precisao do ponto flutuante que eh dita aqui desta maneira eh o numero de bits que essa variavel ocupa no sistema // 100% iterativo e binario // Talvez com assembly executando calculos de baixo nivel em ponto flutuante fique melhor ainda // Mas deste modo eh mais ilustrativo // O melhor de tudo: nao eh necessario saber calculo. Mais facil entender // Da pra fazer com lapis, papel, uma calculadora de feira e alguma paciencia. // Calcular raiz quadrada no papel pode ser mais simples que elevar 2,718181 à 3,14159216 // O unico inconveniente eh que para tirar logaritmo de base "e", deve-se saber o numero previamente, independente destealgoritmo. // O erro implica na precisao desse valor fornecido e de outros quaisquer, de forma igual. int main (void) { double s = 0.0; double t = exp(1.0); double i = 1.0; double x = 21397534.0; double y = 0.0; double x0 = x; double t0 = t; int flag = 0; if (0<t && t<1) { flag = ~flag; t = 1/t; } // int q = 0; // Apenas para avaliar numero de passos do { while (x>t && t>1) { y += i; x/=t; } // printf("q=%4d\tx= %15.25f\t i= %15.25f\t y= %15.25f\t t= %15.25f\t s= %15.25f\n", q, x, i, y, t, s); s += y; y = 0.0; t = sqrt(t); i /=2.0; // q++; } while (t>1); if (flag) { s = -s; t = 1/t; } // printf("q=%4d\tx= %15.25f\t i= %15.25f\t y= %15.25f\t t= %15.25f\t s= %15.25f\n", q, x, i, y, t, s); printf("%15.25f^%15.25f=%15.25f\n", t0, s, pow (t0,s)); return 0; }
Manipulação de um vetor de registros
Função "Partição de Inteiros" Recursiva COM Tabela Estática em C
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Preciso resolver um erro de DPKG (1)
Melhores Práticas de Nomenclatura: Pastas, Arquivos e Código (2)
Não to conseguindo resolver este problemas ao instalar o playonelinux (1)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta