Página 1 de 1
operador ^ em variaveis float com CCS

Enviado:
19 Jan 2009 09:29
por Diego_Oliveira
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?

Enviado:
19 Jan 2009 09:34
por ffcprog
^ = 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
Re: operador ^ em variaveis float com CCS

Enviado:
19 Jan 2009 09:38
por andre_luis
Diego,
Usa assim :
- Código: Selecionar todos
c = exp( a * log(b) );
+++

Enviado:
19 Jan 2009 09:40
por Diego_Oliveira
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)

Enviado:
19 Jan 2009 09:41
por Rodrigo_P_A
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

Enviado:
19 Jan 2009 10:01
por Diego_Oliveira
Obrigado a todos, e Rodrigo_P_A com o POW funcionou beleza, porém estava certo quanto a memoria.

Enviado:
19 Jan 2009 21:14
por barboza
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);
}

Enviado:
22 Jan 2009 10:52
por Emilio Eduardo
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!

Enviado:
22 Jan 2009 12:21
por barboza
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.....

Enviado:
22 Jan 2009 15:53
por Emilio Eduardo
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!!

Enviado:
22 Jan 2009 16:23
por barboza
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, ......

Enviado:
22 Jan 2009 18:31
por Emilio Eduardo
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]

Enviado:
22 Jan 2009 18:54
por barboza
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.

Enviado:
22 Jan 2009 19:02
por Emilio Eduardo
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!

Enviado:
22 Jan 2009 19:38
por chrdcv
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!