Haz una pregunta
  Foros de Electrónica » Diseño digital » Interfaces y Programación
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

13/10/2013 #1

Avatar de LaElectronicaMeOdia

Exponentes en CCS
es la primer vez se me presenta la necesidad de usar exponentes en CCS

tengo este codigo:
Código:
#include <16F877A.h> 
//#fuses XT,NOWDT,NOPROTECT,NOLVP 
#use delay(clock= 4000000) 

#include "lcd.c"
#include "kbd_LIB.c"
#include <string.h>
#INCLUDE <stdlib.h>
#INCLUDE <math.h>


void main()
{
   char nume[10];
   char dece [10];
   char actual=0;
   short ed=true;
   
   int i=0,d=0;
   float num1;
   float num2;
   float valor; 
  
   lcd_init();
   kbd_init();   
   port_b_pullups(TRUE); 
   set_tris_c(0xff);

   while(true)
   {  actual=getch();
      switch(actual)
      {  case '+':
             num1= pow(10,2);
            printf(lcd_putc,"%u",num1);
         break;
        default:
         lcd_putc(actual);
         if (ed) {nume[i]=actual;i++; } else {dece[d]=actual;d++;}  
        break;
     }
    }
   }
en el resultado me pone 84 alguien me puede echar una mano, deberia ser 10^2=100

resalto en rojo lo escencial del codigo
13/10/2013 #2


Hola amigo, creo que el error esta en: %u, la u se usa para enteros sin signo, para flotantes se usa la f.


printf(lcd_putc,"%u",num1);
13/10/2013 #3

Avatar de Scooter

jcristhian_1 dijo: Ver Mensaje
Hola amigo, creo que el error esta en: %u, la u se usa para enteros sin signo, para flotantes se usa la f.


printf(lcd_putc,"%u",num1);
Si, en c ando cojo pero yo también creo que es eso.
13/10/2013 #4

Avatar de LaElectronicaMeOdia

algo anda raro.

puse:

num1= pow(10,2);
printf(lcd_putc,"%f",num1);

y me pone 0.00

despues puse:

num1= pow(10,2);
printf(lcd_putc,"%10.5w",num1);

y me pone 35774.33940
13/10/2013 #5

Avatar de Eduardo

LaElectronicaMeOdia dijo: Ver Mensaje
algo anda raro.

puse:

num1= pow(10,2);
printf(lcd_putc,"%f",num1);

y me pone 0.00

despues puse:

num1= pow(10,2);
printf(lcd_putc,"%10.5w",num1);

y me pone 35774.33940
Probá especificando a cantidad de dígitos:

printf(lcd_putc,"%5.2f",num1); // trunca
o
printf(lcd_putc,"%5.2g",num1); // redondea
13/10/2013 #6

Avatar de LaElectronicaMeOdia

yo creo que es el pow(x,y)

pongo:
num1=pow(10,2);
printf(lcd_putc,"%5.2g",num1);

y me pone 0.00

pero si pongo:
num1=10.3456;
printf(lcd_putc,"%5.2g",num1);

me pone 10.35 lo que es correcto redondea a 2 digitos.
13/10/2013 #7

Avatar de Eduardo

LaElectronicaMeOdia dijo: Ver Mensaje
yo creo que es el pow(x,y)
Si, capaz que al compilar no cambia el 'y' entero a float.

¿Y con pow( 10. , 2. )?
13/10/2013 #8

Avatar de Gudino Roberto duberlin

Hola Amigo, bueno estoy similar que Scooter en C, pero en lugar de utilizar num1= pow(10,2); prueba con num1=10^2;
13/10/2013 #9

Avatar de Scooter

No, el operador "^" es para hacer un OR o algo así, no para potenciar.

Siendo un número conocido y una potencia conocida a lo mejor sale mejor hacer un bucle; si es un entero elevado a un entero sale entero y no float y eso requere mucha menos máquina
Algo así:
int potencia(a,b){
potencia = a;
for(int x, x<b,x++){
potencia= a * potencia;
}
return potencia;
}

Seguro que tiene errores pero algo así pudría ser mas rápido que una potencia genérica de float elevado a float.
13/10/2013 #10

Avatar de LaElectronicaMeOdia

Me parece que si es un error del ccs ya revice la librería de math para hacerlo directamente con exp y log y sigue haciendo las cosas mal voy a intententar hacerlo a "piedra y cincel" con el ciclo for como me sugieres scooter
13/10/2013 #11
Moderador

Avatar de D@rkbytes

A mi me funciona bien, el resultado de pow(10,2) me dá "99.99"

Usé este simple código para probar...
Código:
#include <16f877a.h>
#use     delay(crystal = 4MHz)
#include <lcd.c>
#include <math.h>

void main(){
   float num_x=10,num_y=2,res;
   lcd_init();
      
      res = pow(num_x,num_y);
      printf(lcd_putc,"\fValor: %f",res);
}
Saludos.
13/10/2013 #12

Avatar de Gudino Roberto duberlin

Scooter dijo: Ver Mensaje
No, el operador "^" es para hacer un OR o algo así, no para potenciar.

Siendo un número conocido y una potencia conocida a lo mejor sale mejor hacer un bucle; si es un entero elevado a un entero sale entero y no float y eso requere mucha menos máquina
Algo así:
int potencia(a,b){
potencia = a;
for(int x, x<b,x++){
potencia= a * potencia;
}
return potencia;
}

Seguro que tiene errores pero algo así pudría ser mas rápido que una potencia genérica de float elevado a float.
Es verdad Scooter el comentario que haces sobre el operador "^", se utiliza para hacer mascara XOR.
14/10/2013 #13

Avatar de Scooter

Por gusto habría que medir el tiempo de pow y del bucle a ver. Creo que el bucle es mas rápido.
14/10/2013 #14

Avatar de Eduardo

Scooter dijo: Ver Mensaje
Por gusto habría que medir el tiempo de pow y del bucle a ver. Creo que el bucle es mas rápido.
El pow es MUCHO mas costoso computacionalmente.

Cuando el exponente es entero es una burrada usarlo, para eso se escribe directamente x*x, x*x*x etc (o se usa un #define, o un rutina) . Ni hablar si los dos son enteros.
Tiene que usarse solamente con exponentes reales o racionales (pow(x,1.25), pow(x,0.3333333) que es cuando realmente se la necesita, no para evaluar un polinomio.


Muchas veces veo que usan con total tranquilidad tipos float con variables que son siempre enteras. Lo mismo que antes, las operaciones en punto flotante son MUCHO mas costosas computacionalmente que en enteros.
Solamente tiene sentido cuando debido al rango de las variables y al tipo de operaciones a realizar pueda haber overflow/underflow.
Aunque tampoco es solución mágica usar float, porque si no se tiene cuidado, debido a los errores de redondeo/truncamiento le va a dar cualquier cosa.
Cuando pasa esto último ni se dan cuenta, le echan la culpa al compilador, al micro o al autor del algoritmo
14/10/2013 #15

Avatar de LaElectronicaMeOdia

a darkbytes:

ya probe tu codigo y no me funciono, estoy pensando que mi libreria math tiene algun error, quizas causado por mi accidentalmente o asi estaba, podrias pasarme la tuya para verificar que sea eso.

a eduardo:

analice el codigo del pow y efectivamente es un desperdicio de recursos, al ultimo voy a hacer lo que dices del x*x*x*x etc porque si son enteros ambos, en realidad lo que quiero es de un entero pasarlo a decimales

es decir si tengo 12345 (entero) pasarlo a decimal .12345 la formula qu pensaba utilizar es:

12345 / (10^5) =.12345 el 12345 esta almacenado en un arreglo es decir:
valor[0]=1
valor[1]=2
valor[2]=3
valor[3]=4
valor[4]=5
del arreglo lo paso con el atoi a una variable que es la que quiero pasar a decimales, espero haberme explicado comento esto para darles un panorama mas amplio de lo que pretendo. quizas hay un algoritmo mas eficiente que desconozco.
14/10/2013 #16
Moderador

Avatar de D@rkbytes

LaElectronicaMeOdia dijo: Ver Mensaje
ya probé tu código y no me funcionó, estoy pensando que mi librería math tiene algun error, quizás causado por mi accidentalmente o así estaba, ¿podrías pasarme la tuya para verificar que sea eso?
Espero que sea eso, a mi si me muestra bien los resultados, si no, tendrás que reinstalar o actualizar el programa.

Suerte.
Archivos Adjuntos
Tipo de Archivo: zip MATH.zip (7,5 KB (Kilobytes), 26 visitas)
14/10/2013 #17

Avatar de Eduardo

LaElectronicaMeOdia dijo: Ver Mensaje
...
analice el codigo del pow y efectivamente es un desperdicio de recursos, al ultimo voy a hacer lo que dices del x*x*x*x etc porque si son enteros ambos, en realidad lo que quiero es de un entero pasarlo a decimales

es decir si tengo 12345 (entero) pasarlo a decimal .12345 la formula qu pensaba utilizar es:

12345 / (10^5) =.12345 el 12345 esta almacenado en un arreglo es decir:
valor[0]=1
valor[1]=2
valor[2]=3
valor[3]=4
valor[4]=5
del arreglo lo paso con el atoi a una variable que es la que quiero pasar a decimales, espero haberme explicado comento esto para darles un panorama mas amplio de lo que pretendo. quizas hay un algoritmo mas eficiente que desconozco.
Pero 10^5 es una constante, no hay que calcular nada. Simplemente escribir 12345/100000.

También se puede implementar sin atoi con cadenas de longitud variable.
Si k fuera el índice del último dígito hacés:

Código:
    int i = k ;
    valorfloat = valor[i] - 0x30 ;
    valorfloat /= 10. ;
    do {        
        valorfloat += valor[--i] - 0x30 ;
        valorfloat /= 10. ;
    } while(i>0) ;
De todas formas, sigo sin tener claro para que convertís la cadena a float .12345
15/10/2013 #18

Avatar de LaElectronicaMeOdia

Pero 10^5 es una constante, no hay que calcular nada. Simplemente escribir 12345/100000.
no, puse el 10^5 porque 12345 son 5 digitos si tuviera 123 seria 10^3 etc el exponente lo manejare con un contador variable

De todas formas, sigo sin tener claro para que convertís la cadena a float .12345
estoy intentando hacer una calculadora con decimales, yo digito una tecla y esa tecla va a un arreglo para enteros por ejemplo enteros[10] al presionar el punto decimal se empiezan a ir a otro arreglo por ejemplo decimales[10] en cada caso hay una variable como contador que se va incrementado cada que se agrega un digito, la idea es sumar en una variable float ambos arreglos o sea enteros+ decimales.

voy a intentar implementar el codigo que me facilitaste.

---------- Actualizado después de 30 minutos ----------

a darkytes:

reemplace la libreria y ya funciono muchas gracias, pero efectivamente si pongo pow(10,2) me pone 99.99, me quedo con la inquietud si yo dañe la libreria o la version que tengo esta mal, que por cierto tuve que reemplazar todos los float32 por float mi version de ccs no tiene el float32.
15/10/2013 #19

Avatar de Scooter

Los float acumulan error siempre. Los de un pc igual son de 8 o mas bytes y no es perceptible, si los del pic son de 6 bytes o menos se nota mas, a cambio es mas rápido.
15/10/2013 #20

Avatar de Eduardo

LaElectronicaMeOdia dijo: Ver Mensaje
...estoy intentando hacer una calculadora con decimales, yo digito una tecla y esa tecla va a un arreglo para enteros por ejemplo enteros[10] al presionar el punto decimal se empiezan a ir a otro arreglo por ejemplo decimales[10] en cada caso hay una variable como contador que se va incrementado cada que se agrega un digito, la idea es sumar en una variable float ambos arreglos o sea enteros+ decimales.
Si se trata de una calculadora "demo", para eso usá directamente atof().
Pero si lo que buscás es que realmente trabaje como una calculadora, con float (32bits) te quedás re-corta.

El tipo float no te sirve para operaciones genéricas porque al ser grande el error por truncamiento, si las operaciones no se hacen de una forma que minimice el error te da cualquier cosa.

Para algo genérico tiene que ser por lo menos doble precisión (64bit), el problema que vas muerta con el CCS y no conozco librerías que contemplen un "float64" (tendrías que escribir tus propias rutinas de punto flotante)
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Interfaces y Programación

Lenguajes de programación, gestión y manejo de puertos

Cerrar
Foros de Electrónica » Diseño digital » Interfaces y Programación

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.