¿Cómo convertir un int en 4 chars?

Started by panreyes, June 05, 2015, 03:18:25 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

panreyes

Si no me equivoco demasiado, puedo convertir un int en 4 chars, ¿cierto?


El objetivo es optimizar mandando los datos en binario en vez de en texto. En vez de mandar este número:
14898413
Que se conviertan en esto:
ï╚♪♀


¿Ideas?

Fuynfactory

se podría intentar hacerlo en C, C++ y meter la función en una libreria y usarlo....

Erkosone

Pero Pixel, un INT ocupa 4 byte´s en memoria y 4 char también ocupan 4 byte´s en memoria, en realidad son la misma cosa, en que contexto quieres usar esto? enviarlo por red quizá?

panreyes

@erkosone, exactamente, enviarlo por red :)
@fuynfactory: Me imagino. Si puedo evitarlo, mejor

DjSonyk

La función ATOI puedes transformar un numero INT en una cadena STRING, y luego por ejemplo con SUBSTR puedes ir pasándolos a CHAR....

panreyes

@DjSonyk: Pierde el sentido, no optimizaría nada. Acabaría con el mismo número de chars que de cifras, en vez de 4 como mucho.

DjSonyk

Pues creo que te va a tocar currarte una librería...

FreeYourMind

pues te curras un algoritmo de compresion/decompresion de datos

gecko

lo que no se muy bien es como dividir ese int en 4 ints distintos.

despues no funcionaria ir haciendo:

string palabra = "abcd";
palabra[0] = int_primero;
palabra[1] = int_segundo;

y asi??

(no tengo ni idea si eso es posible, pero en mi cabeza eso compila perfecto xD )
Torres Baldi Studio
http://torresbaldi.com

JaViS

volviendo a la pregunta de Erkozone. Porque un string, si el int ocupa lo mismo?



Working on Anarkade. A couch multiplayer 2D shooter.

panreyes

Voy a ver si lo explico mejor.


Un int son 4 bytes y un char es 1 byte. Si copio la memoria de esos 4 bytes del int en un char[4], tendré 4 símbolos de aparente garbage que podré añadir a una cadena (en teoría, probablemente la corrompa) que luego enviaría por red.


Actualmente estoy mandando por red todas las creaciones, actualizaciones y destrucciones de procesos para luego reproducirlas en el cliente, y el formato que utilizo actualmente envía cientos de lineas como esta:
pu,512,234,382,295,138,634,458,0,584,1249;

Y lo que quiero es convertir esos valores en formato binario para poder optimizarlo un poco más. Se quedaría algo parecido a esto:
pu,►×­{♫,hÆ6♦,↑⌂ùÉ,!.ë☼, ...


El objetivo es reducir un poco la tasa de transferencia de datos, que actualmente puede llegar a unos 30000 bytes * 60 fps = 1800000 bytes/s = 1757 kB/s = 1,71mBps = 13,73mbps

kim-elet-o

Puedes usar mascaras y desplazamientos para hacerlo:


int valor = 123456;              // Entero a convertir a chars.
char resChar[4];                  // Array de chars resultado de la conversion.

For (int i = 0; i < 4; i++)         // el proceso se repite 4 veces una vez por char a obtener.
    resChar[i] = valor & 255;    // se realiza una operacion AND del entero para obtener el byte mas bajo del entero,
    valor = valor >> 8;              // se desplaza el valor del entero a convertir, 8 bits a la derecha.
End
|/
|\im-elet-o el yayo programador.

panreyes

Gracias Kim, eso tiene pinta de que me funcionará :)


Aunque... ¿Y lo contrario? ¿Volver a convertir esos 4 chars en un int? xD

Drumpi

int valor = 123456;              // Entero a convertir a chars.
char resChar[4];                  // Array de chars resultado de la conversion.

For (int i = 3; i >=0 ; i--)         // el proceso se repite 4 veces una vez por char a obtener.
    valor = valor << 8;              // se desplaza el valor del entero a convertir, 8 bits a la derecha.
    valor += resChar[i];      // se realiza una operacion AND del entero para obtener el byte mas bajo del entero,
End


Fácil y con fundamento :)
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

panreyes

#14
Gracias Drumpi.

Luego, en teoría, ¿esto debería de funcionar?

import "mod_say"

Global
   char net_cbuffer[4];
   
Begin
   itoc(23456);
   say(net_cbuffer);
   say(ctoi());
   return;
End

Function itoc(int valor);
Private
   i;
Begin
   For(i=0;i<4;i++)         // el proceso se repite 4 veces una vez por char a obtener.
      net_cbuffer[i] = valor & 255;    // se realiza una operacion AND del entero para obtener el byte mas bajo del entero,
      valor = valor >> 8;              // se desplaza el valor del entero a convertir, 8 bits a la derecha.
   end
End

Function ctoi();
Private
   i;
   valor;
Begin
   For(i=3;i>=0;i--)         // el proceso se repite 4 veces una vez por char a obtener.
      valor = valor << 8;              // se desplaza el valor del entero a convertir, 8 bits a la derecha.
      valor += net_cbuffer[i];      // se realiza una operacion AND del entero para obtener el byte mas bajo del entero,
   End
   return valor;
End


[Editado] Me corrijo: Funciona :D
[Editado2] Me vuelvo a corregir, casi funciona!


¡Más difícil todavía!


¿Y cómo se podría hacer para que funcionara con números negativos? xD