operador ^ em variaveis float com CCS

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

operador ^ em variaveis float com CCS

Mensagempor Diego_Oliveira » 19 Jan 2009 09:29

Bom tive a necesidade de utilizar este calculo:

Float a;
Float b;
Float c;
a = 0,52;
b = 0,62034; // valores de exemplo
c = a ^ b;

alguém teria ideia de como fazer isso de uma maneira alternativa pois o compilador não me deixa realizar este tipo de calculo com variaveis do tipo float?
Avatar do usuário
Diego_Oliveira
Nibble
 
Mensagens: 79
Registrado em: 05 Abr 2008 15:18
Localização: Rio Grande do Sul

Mensagempor ffcprog » 19 Jan 2009 09:34

^ = bitwise exclusive OR (XOR); "compares" "pairs of bits" and returns 1 if the bits are complementary, otherwise returns 0.

Tem certeza que é este comando mesmo que você quer utilizar ?

ffcprog
ffcprog
Byte
 
Mensagens: 145
Registrado em: 14 Fev 2007 23:16

Re: operador ^ em variaveis float com CCS

Mensagempor andre_luis » 19 Jan 2009 09:38

Diego,

Usa assim :

Código: Selecionar todos
c = exp( a * log(b) );


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor Diego_Oliveira » 19 Jan 2009 09:40

O Calculo real que quero fazer é este abaixo, ele originalmente é de uma planilha do excel em uma macro escrita em VBA estava tentando convertela para minha aplicação.

A = 0.000085511
B = 2.0087
C = 37.811
Ue = (-Log(1 - (UR / 100)) / (A * (T + C))) ^ (1 / B)
Ue = Ue * 100 / (100 + Ue)
Avatar do usuário
Diego_Oliveira
Nibble
 
Mensagens: 79
Registrado em: 05 Abr 2008 15:18
Localização: Rio Grande do Sul

Mensagempor Rodrigo_P_A » 19 Jan 2009 09:41

Diego_Oliveira escreveu:O Calculo real que quero fazer é este abaixo, ele originalmente é de uma planilha do excel em uma macro escrita em VBA estava tentando convertela para minha aplicação.

A = 0.000085511
B = 2.0087
C = 37.811
Ue = (-Log(1 - (UR / 100)) / (A * (T + C))) ^ (1 / B)
Ue = Ue * 100 / (100 + Ue)


em VB o simbolo " ^ " é de potência

em C vc tem que usar o POW

se prepara pra comer muita memória do microcontrolador, e torce pro CCS dar o resultado correto .

boa sorte
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2237
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Mensagempor Diego_Oliveira » 19 Jan 2009 10:01

Obrigado a todos, e Rodrigo_P_A com o POW funcionou beleza, porém estava certo quanto a memoria.
Avatar do usuário
Diego_Oliveira
Nibble
 
Mensagens: 79
Registrado em: 05 Abr 2008 15:18
Localização: Rio Grande do Sul

Mensagempor barboza » 19 Jan 2009 21:14

Diego_Oliveira escreveu:Obrigado a todos, e Rodrigo_P_A com o POW funcionou beleza, porém estava certo quanto a memoria.



Não da pra fazer assim?

Código: Selecionar todos
float p_pow (float op, int pow)
{
    if (pow == 0)
    {
        return 1;
    }

    while (--pow)
    {
       op *= op;
    }
    return op;
}


main()
{
    float c;

   c = p_pow ( 10, 2);
}
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor Emilio Eduardo » 22 Jan 2009 10:52

Se for com numeros inteiros no expoente é mais rápido no processamento assim:

Código: Selecionar todos
p_pow(float base, int exp)
{
         if(exp==2)
         {
                  return base*base;
          }
          else
          {
                   res = p_pow(base,pow/2);
                   if(exp%2)
                   {
                   return res*res*base;
                   }
                   else
                   {
                   return res*res;
                   }
           }
}


Deve funcionar bem pra caramba no quesito velocidade pois o algoritmo é O(log n) o que vai diminuir o número de instruções a ser feitas no final mas não sei como o PIC trata a pilha de chamadas o que pode complicar a utilização de funções recursivas nele. Se fosse em um computador eu certamente usaria esse algoritmo!

Valeu!
Emilio Eduardo
Bit
 
Mensagens: 44
Registrado em: 13 Jan 2009 19:07

Mensagempor barboza » 22 Jan 2009 12:21

Emilio Eduardo escreveu:
Deve funcionar bem pra caramba no quesito velocidade pois o algoritmo é O(log n) o que vai diminuir o número de instruções a ser feitas no final mas não sei como o PIC trata a pilha de chamadas o que pode complicar a utilização de funções recursivas nele. Se fosse em um computador eu certamente usaria esse algoritmo!

Valeu!



Não vou levar em conta a recursividade/stack em microprocessadores, pois é sempre problema, mas:

Sem fazer uma analise mais profunda, não consigo ver como uma função com testes (if), passagem e recebimento de retornos a funções (recursiva), divisão e teste (/2 e %), multiplicações (até dupla) possa ser mais rápida que um simples loop de subtração e teste (while(--pow) e uma multiplicação.

Realmente cabe uma analise mais profunda.....
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor Emilio Eduardo » 22 Jan 2009 15:53

Barboza, o truque está quando o expoente for alto, pois o código será executado log de n vezes sendo n o expoente, assim talvez com um expoente 5 não seja rápido mas um expoente 1000 vai ser muito mais rápido, apesar de gastar muito mais memória também! Pois se por exemplo o expoente for 1024 você terá a função rodando 10 vezes que multiplicadas pelo número de instruções ali dentro talvez dê 50 instruções, muito diferente de executar 1000 multiplicações!!
Emilio Eduardo
Bit
 
Mensagens: 44
Registrado em: 13 Jan 2009 19:07

Mensagempor barboza » 22 Jan 2009 16:23

Emilio Eduardo escreveu:Barboza, o truque está quando o expoente for alto, pois o código será executado log de n vezes sendo n o expoente, assim talvez com um expoente 5 não seja rápido mas um expoente 1000 vai ser muito mais rápido, apesar de gastar muito mais memória também! Pois se por exemplo o expoente for 1024 você terá a função rodando 10 vezes que multiplicadas pelo número de instruções ali dentro talvez dê 50 instruções, muito diferente de executar 1000 multiplicações!!



Mas no mínimo a cada execução da sua rotina, existirá uma multiplicação, além das comparações, ......
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor Emilio Eduardo » 22 Jan 2009 18:31

Barboza, isso é claro que vai acontecer.

A diferença é que quando ele rodar por exemplo a primeira vez com um expoente 16 ele vai chamar uma vez a rotina do expoente de oito e essa chamará a rotina de 4 que vai chamar a de dois que vai retornar a base*base. Assim, se você for contar quantas multiplicações foram realizadas:

Código: Selecionar todos

chamada com expoente 2: base*base ----------------> 1
chamada com expoente 4: base^2*base^2 ---------->2
chamada com expoente 8: base^4*base^4----------->3
chamada com expoente 16: base^8*base^8---------->4



Portanto foram feitas somente 4 multiplicações no total, bem melhor do que 15 no seu código!

Abraço![/code]
Emilio Eduardo
Bit
 
Mensagens: 44
Registrado em: 13 Jan 2009 19:07

Mensagempor barboza » 22 Jan 2009 18:54

Oi Emilio!

A recursividade Log n esta claro para mim e vc esta certo (so esqueceu dos custos de divisão ~= multiplicação), minha referencia foi pensando em microcontroladores , onde vc pode ter a multiplicação em hardware (nem todos com float) e com seu algoritmo a cada nova chamada é necessario efetuar uma divisão para passagem de parametro (pow/2) além dos load/store, e no final outra divisão para verificar o resto (%2) e se for impar é uma multiplicação dupla (res*res*base).

Não estou discutindo sexo dos anjos, só comentei sobre a diferença entre os mundos e suas limitações.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor Emilio Eduardo » 22 Jan 2009 19:02

Ok, é claro que quando se tratando de Microcontroladores você têm milhares de vezes a minha experiência, quando o assunto é esse tenho que me render e não posso discutir!

Obviamente se o algoritmo fosse implementado em expoentes maiores em um computador com memória suficiente seria muito mais eficiente o segundo algoritmo!

Parabéns por ter tanta paiência ajudado a todos nesse fórum e Obrigado!
Emilio Eduardo
Bit
 
Mensagens: 44
Registrado em: 13 Jan 2009 19:07

Mensagempor chrdcv » 22 Jan 2009 19:38

Não seria melhor analisar detalhadamente a possível resposta do transdutor (acredito eu que a fórmula matemática seja proveniente de um), depois verificar a melhor interpolação para a mesma? Assim, possivelmente nem seria necessário a utilização de tipos flutuantes. Na maioria dos casos (99%), não é usado tipos flutuantes para cálculos...na grande maioria das vezes ou resolve por interpolação ou então por uma lookup table mesmo...

A razão da não utilização de tipos flutuantes é óbvia, pois uC´s (4, 8, 16 e até mesmo alguns de 32bits) não possuem uma ALU que suporte tais tipos, então resolve-se as operações por software o que implica a utilização em alguns casos de bibliotecas não muito confiáveis (veja o número de correções do compilador CCS - arghhh). Isso acarreta em uma grande quantidade de memória de programa e dados utilizada, além de uma perda substancial de performance dado que o tempo gasto para realizar todo o cálculo será de forma iterativa (lembre-se que em embedded, recursão quase sempre é proibitiva - no seu caso totalmente pois o uC não possui um arquitetura que suporte pilha em software e sim por hardware).

Thats all!

Christian - o ogro!
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

cron

x