Autor Tema: alternativa funcion Float2Fract  (Leído 3022 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ElEspañolito

  • PIC10
  • *
  • Mensajes: 6
alternativa funcion Float2Fract
« en: 12 de Julio de 2011, 12:46:49 »
Buenos dias,

la cuestion es que estaba jugando con los dos formatos float y fractional y, segun las librerias, para pasar de un formato a otro estan las funciones respectivas Float2Fract y Fract2Float. La cuestion es que segun el simulador, viendo las variables con Wach y los tiempos de ejecucion con el StopWatch, si multiplico un float por el numero 1 en fractional ( 0x7FFF en codificacion hexadecimal) hace lo mismo y muchisimo mas rapido. Pongo un ejemplo:

Código: [Seleccionar]
fractional rotz
rotz=Float2Fract(0.01f);
rotz=0x7FFF*0.01f;

utilizando la funcion tardo 1886 ciclos y el resultado es de 0.0100097656
utilizando la multiplicacion tardo 2 ciclos y el resultado es de 0.00997924805

soy novatillo con los dsPIC asi que no estoy muy familiarizado con el formato fractional. Que os parece el metodo? se puede utilizar o el simulador "me esta engañando"

un saludo

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: alternativa funcion Float2Fract
« Respuesta #1 en: 12 de Julio de 2011, 18:19:01 »
Probaste si para todos los numeros es asi ?

Código: [Seleccionar]
#define Q15(X) \
   ((X < 0.0) ? (int)(32768*(X) - 0.5) : (int)(32767*(X) + 0.5))

#if     DATA_TYPE==FLOATING             /* [ */
#define Float2Fract(aVal)       (aVal)  /* Identity function */
#define Fract2Float(aVal)       (aVal)  /* Identity function */
#else   /* ] */
extern fractional Float2Fract (         /* Converts float into fractional */
   float aVal                           /* float value in range [-1, 1) */
);
extern float Fract2Float (        /* Converts fractional into float */
   fractional aVal         /* fract value in range {-1, 1-2^-15} */
);
#endif  /* ] */

Disculpa pero no entiendo nada de C,, imaginare q la funcion Q15 es la que realiza esa conversion... A simple vista se puede ver que  hace una restas o suma dependiendo del signo

Multiplica por 0x8000 y le resta -0.5 decimal..  o casi 0x1.. es por eso que da aproximado a multiplicarlo por 0x7FFF . Pero como te digo, no te aseguro nada ya que C me puede... xD, que respondan lo que saben C..

**************** EDIT *******************

Sacado de Wikipedia

Citar
Conversion
 Float to Q

To convert a number from floating point to Qm.n format:

    Multiply the floating point number by 2n
    Round to the nearest integer

Q to Float

To convert a number from Qm.n format to floating point:

    Convert the number to floating point as if it were an integer
    Multiply by 2−n

Pasar de Float a Q15.. multiplica el valor por 2^15 = 32768 = 0x8000 y luego redondea.. deberias tener activo el bit RND del registro CORCON para un redondeado convencional. SI alguno sabe mas y le estoy pifiando feo,, q me avize xD jeje

Desconectado ElEspañolito

  • PIC10
  • *
  • Mensajes: 6
Re: alternativa funcion Float2Fract
« Respuesta #2 en: 12 de Julio de 2011, 18:54:52 »
el resultado de multiplicar por 0x8000 o por 0x7FFF es el mismo (comprobado con el StopWatch). Si no estoy equivocado el rango superior del formato Q15, es decir el numero 1, es el 0x7FFF asi que multiplicar por 0x8000 supongo que lo interpreta igual. Lo que lleva a afirmar que es una forma valida de pasar de float a Q15 y que la función es inutilmente lenta...

Respecto al tema del redondeo, no lo hace directamente? Pregunto desde la ignoracia porque esos registros todavia no los he tocado,...

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: alternativa funcion Float2Fract
« Respuesta #3 en: 12 de Julio de 2011, 19:58:38 »
Con el stopwath ves el tiempo mejor miralo con el Watch...

Ya q justamente el dsPIC trae un motor DSP que es capaz de multiplicar en 1 ciclo, asi que no hay diferencias contra lo que lo multipliques ( 0x7FFF o 0x8000)

Lo que decia yo era el resultado...

Con respecto al redondeo o saturacion todo se maneja con el registro CORCON,, pero yo hablo mas en ASM... En C imagino que habra una simple sentencia que haga el redondeo..

Si es asi nomas la operacion, Y se manejan como fraccionarios utilizara los bits <31:16> del acumulador y eliminara los demas... o sea los trunca,, sin modificar el ultimo bit.

Espero la respuesta de otra persona.. que sepa un poco mas que yo.