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?
se podría intentar hacerlo en C, C++ y meter la función en una libreria y usarlo....
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á?
@erkosone, exactamente, enviarlo por red :)
@fuynfactory: Me imagino. Si puedo evitarlo, mejor
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....
@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.
Pues creo que te va a tocar currarte una librería...
pues te curras un algoritmo de compresion/decompresion de datos
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 )
volviendo a la pregunta de Erkozone. Porque un string, si el int ocupa lo mismo?
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
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
Gracias Kim, eso tiene pinta de que me funcionará :)
Aunque... ¿Y lo contrario? ¿Volver a convertir esos 4 chars en un int? xD
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 :)
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
Drumpi, prueba cambiar la linea...
valor += net_cbuffer[i]; // esto una suma aritmetica que tiene en cuenta los signos.
por....
valor = valor | net_cbuffer[i]; // la funcion OR es una suma logica que no tiene en cuenta los signos.
haber que tal
Bien visto, Kim-elet-o. Me lo apunto.
global
int a;
char ch4[3];
begin
a = 12345678;
*((int *)&ch4)=a;
end
no es portable entre plataformas de diferente byteorder, pero supongo que no estas preocupado por eso.
si necesitas que sea portable necesitas hacer la inversion de bytes, segun plataforma.