/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

BIT ordering

 
      Índice del Foro elrincondelc.com -> C/C++ en General
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
anaisgcristal



Registrado: 04 Abr 2007
Mensajes: 25

MensajePublicado: 09/03/2008 6:24 am
Título: BIT ordering

Hola a todos,
Estoy trabajando en una maquina little endian con unos datos big endian..y obviamente esto trae una serie de problemas...Hasta ahora me han recomendado una funcion de este tipo:

Código:
float ByteSwap2 (float nLongNumber)
{
  return (((nLongNumber&&0x000000FF)<<24)+((nLongNumber&&0x0000FF00)<<8)+
  ((nLongNumber&&0x00FF0000)>>8)+((nLongNumber&&0xFF000000)>>24));
}


Hay alguna otra forma mas simple de hacerlo....Y como hacerlo para máquinas de 64 byts? Alguno ha tenido que resolver algun problema similar...?

Gracias de antemano, Anaïs
Volver arriba
mamntc02



Registrado: 30 Abr 2007
Mensajes: 384

MensajePublicado: 10/03/2008 1:35 am
Título:

Hola,

En mi humilde opinión te han informado mal. Pq usas tipos float, q son tipos en punto flotante?
Una manera de hacerlo q no depende ni del compilador ni de la plataforma para 16, 32 y 64 bits:
Código:
inline void endian_swap(unsigned short& x)
{
    x = (x>>8) |
        (x<<8);
}

inline void endian_swap(unsigned int& x)
{
    x = (x>>24) |
        ((x<<8) & 0x00FF0000) |
        ((x>>8) & 0x0000FF00) |
        (x<<24);
}

// Nota: __int64 para MSVC, "long long" para gcc
inline void endian_swap(unsigned __int64& x)
{
    x = (x>>56) |
        ((x<<40) & 0x00FF000000000000) |
        ((x<<24) & 0x0000FF0000000000) |
        ((x<<8)  & 0x000000FF00000000) |
        ((x>>8)  & 0x00000000FF000000) |
        ((x>>24) & 0x0000000000FF0000) |
        ((x>>40) & 0x000000000000FF00) |
        (x<<56);
}

Hay un par de funciones ntohl() y htonl() q en ciertos sistemas hacen los mismo, pero no para la misma finalidad, ya q son funciones para convertir los datos q nos llegan por red. No obstante, estas funciones no funcionan en todas las plataformas y tampoco son portables, por lo q no son recomendables para cambiar el endianness.

Saludos
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 4181
Ubicación: Mexico

MensajePublicado: 11/03/2008 7:46 am
Título: Re: BIT ordering

anaisgcristal escribió:
Estoy trabajando en una maquina little endian con unos datos big endian..y obviamente esto trae una serie de problemas...Hasta ahora me han recomendado una funcion de este tipo

Esa funcion no daria el resultado esperado, al menos no en C estandar ya que en este los operadores de desplazamiento solo pueden aplicarse a tipos enteros.

anaisgcristal escribió:
Hay alguna otra forma mas simple de hacerlo....Y como hacerlo para máquinas de 64 byts?

Solo tienes que utilizar un bucle que itere sobre los bytes que conforman el tipo y tambien seria mejor utilizar el tipo double en lugar del tipo float.

Una forma de implementar la funcion seria (mas o menos asi):
Código:
double fn_swap(double num)
{
   unsigned char *p;
   unsigned char *q;
   unsigned char aux;
   
   p = (unsigned char *) #
   q = p + sizeof(double) - 1;
   
   while (p < q){
      aux = *p;
      *p = *q;
      *q = aux;
     
      p++;
      q--;
   }
   
   return num;
}


Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
anaisgcristal



Registrado: 04 Abr 2007
Mensajes: 25

MensajePublicado: 11/03/2008 11:38 am
Título:

Gracias a ambos, entre las dos funciones, he logrado resolver el problema Very Happy
Ademas de corregir un error q tenia...
Volver arriba
cheroky



Registrado: 22 Sep 2005
Mensajes: 1411
Ubicación: En ecx esperando un call

MensajePublicado: 12/04/2008 5:11 pm
Título:

Si la eficiencia es crítica una posible solución es implementarla en inline assembly.
En este caso con gcc vía clobber, totalmente portable para la arquitectura ia32.

Código:

#include <stdint.h>

/*           */


uint64_t foo(uint64_t v)
{
   __asm__ __volatile__
   (   
         "subl $8, %%esp           \n"
         "movl $7, %%edi           \n"
         "movl $8, %%esi           \n"
          "lp:                     \n"
         "movb (%%esi,%%ebp), %%al \n"
         "movb %%al,(%%esp, %%edi) \n"
         "inc %%esi                \n"   
         "dec %%edi                \n"
         "cmp $16, %%esi           \n"
         "jnz lp                   \n"
         "movl (%%esp), %%eax      \n"
         "movl %%eax, 8(%%ebp)     \n"
         "movl 4(%%esp), %%eax     \n"
         "movl %%eax, 12(%%ebp)    \n"
         "addl $8, %%esp           \n"   
         :::"eax","memory"
    );
   
    return v;
}
    /*           */


S2.
_________________
The point is that programs are meant to be read by people, not just computers.
Volver arriba
      Índice del Foro elrincondelc.com -> C/C++ en General
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com