Foros del Web » Programando para Internet » PHP »

Convertir Numeros a Caracteres ASCII

Estas en el tema de Convertir Numeros a Caracteres ASCII en el foro de PHP en Foros del Web. Estoy necesitando pasar con php numeros enteros a ASCII, el tema es que al usar la funcion ORD(), me convierte solo de a 1 solo ...
  #1 (permalink)  
Antiguo 04/10/2010, 05:48
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Desacuerdo Convertir Numeros a Caracteres ASCII

Estoy necesitando pasar con php numeros enteros a ASCII, el tema es que al usar la funcion ORD(), me convierte solo de a 1 solo caracter, o sea, si yo tengo 0046 en ascii los 00 me los tomaria como 4848 por ejemplo... pero yo quiero el valor de "00" no de cada caracter por separado.. espero que me entiendan....

A ver, voy de nuevo... lo que necesitaria hacer es para tener mas seguridad...

Pasar entero a Hexadecimal y de Hexadecimal a AsCII... alguna idea de como puedo hacerlo...

Gracias
  #2 (permalink)  
Antiguo 04/10/2010, 06:07
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

Pero es que no existe un valor 00 en el ASCII. Si existiera ord te devolvería ese valor.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #3 (permalink)  
Antiguo 04/10/2010, 06:08
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Exclamación Respuesta: Convertir Numeros a Caracteres ASCII

En realidad si existe, existen todos los numeros.. a ver, era solo a exprecion de ejemplo... lo que yo quiero que es que me interprete todo el numero en ascii y no separado caracter por caracter....

Saludos
  #4 (permalink)  
Antiguo 04/10/2010, 06:12
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

¿Existe un valor 00 en el ASCII? Me gustaría saberlo. Bueno, de que valor a que valor quieres que se convierta. Es decir muestra un ejemplo (y si varios mucho mejor).
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #5 (permalink)  
Antiguo 04/10/2010, 06:26
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Respuesta: Convertir Numeros a Caracteres ASCII

Con esto mas o menos lo logro..

function hex2ascii($hex){
$ascii='';
for($i=0; $i<strlen($hex); $i=$i+2) {
$ascii.=chr(hexdec(substr($hex, $i, 2)));
}
return($ascii);
}
  #6 (permalink)  
Antiguo 04/10/2010, 06:58
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Respuesta: Convertir Numeros a Caracteres ASCII

A ver si me das una mano.... mira... tengo esta funcion que me convierte un hexadecimal a como floatente... ahora lo que yo tengo que hacer es volver a convertir ese comoflotante a hexadecimal si me preguntas por que, no te voy a saber responder, mi jefe me lo pide, y despues de ser un hexadecimal reconvertido, tengo que pasarlo a ASCII...

function comaFlotante($val){
$entero = hexdec($val);
$ascci = pack('i', $entero);
$float = unpack('f', $ascci);

return $float[1];
}

esto me convierte un hexadecimal en comafloatente... ahora

esto:

function hex2ascii($hex){
$ascii='';
for($i=0; $i<strlen($hex); $i=$i+2) {
$ascii.=chr(hexdec(substr($hex, $i, 2)));
}
return($ascii);
}

Me convierte un hexadecimal en ascii pero dudo de su funcionamiento...

Alguna idea ????
  #7 (permalink)  
Antiguo 04/10/2010, 07:10
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

Si el hexadecimal 0046 es la letra F entonces lo que puedes hacer es algo así
Código PHP:
Ver original
  1. <?php
  2. echo chr(0x0046);
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 04/10/2010, 07:18
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Respuesta: Convertir Numeros a Caracteres ASCII

El tema es que no funcionaria con un coma flotante.. por ejemplo.. el numero 40 en coma flotante es 5.6051938572993E-44 y lo que necesito es pasar esto a ascii previo a hexa... o sea seria asi...

de 40, a coma floatente: 5.6051938572993E-44 y de este numero a hexadecimal... y de ese hexadecimal a ASCII...
  #9 (permalink)  
Antiguo 04/10/2010, 07:40
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

¿Pero y lo que te indiqué hace un tiempo en este tema no te ha resultado? http://www.forosdelweb.com/f18/pasar...otante-840095/

PD: No me contestaste la pregunta de aquella vez , así que aprovecho y para que me la contestes
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #10 (permalink)  
Antiguo 04/10/2010, 07:51
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Respuesta: Convertir Numeros a Caracteres ASCII

Pues ahora te comento.... cual es todo mi rollo...

Tengo un archivo llamado niveles.log que tiene el siguiente contenido:

niveles.log:
C¾› L/segMontecs QC*Dõ L/segSet Point Q% Norte QDŒ^õ L/seg Sur QDá=× L/seg Saavedra Qmts Sarramea Qmts Error CONTACTOR 1 Error CONTACTOR 2 Corrig. MontecaserosCorrig. Alto Verde Corrigiendo caudal, Error MAX IZQUIERDA Error MAX DERECHA Modo MANUAL Error excede los li_mites. Pase a MANUALPor Favor espere... Proximo error a cor_regir= QÃ*Dõ

Este archivo siempre es de 463 bytes, sin importar su contenido, o sea, los valores dentro pueden cambiar incluso hasta puede estar vacio pero siempre tiene 463 bytes... (desconozco el motivo)...

Lo que hago es pasar todo el contenido a hexadecimal... con esta funcion:

Código PHP:
function ascii2hex($ascii) {
    
$hex '';
    for (
$i 0$i strlen($ascii); $i++) {
    
$byte strtoupper(dechex(ord($ascii{$i})));
    
$byte str_repeat('0'strlen($byte)).$byte;
    
$hex.=$byte."";
    }
return 
$hex;

Y con esto abro el archivo y leeo solo lo que que quiero de esos datos....

Código PHP:
$fp fopen('niveles.log','rb');
$read fread($fp,463);
fclose($fp);

$h ascii2hex($read);
$matriz $h[0].$h[1].$h[2].$h[3].$h[4].$h[5].$h[6].$h[7];
$montecaseros $h[40].$h[41].$h[42].$h[43].$h[44].$h[45].$h[46].$h[47];
$norte $h[116].$h[117].$h[118].$h[119].$h[120].$h[121].$h[122].$h[123];
$sur $h[152].$h[153].$h[154].$h[155].$h[156].$h[157].$h[158].$h[159];
$setPoint $h[84].$h[85].$h[86].$h[87].$h[88].$h[89].$h[90].$h[91];
$error $h[918].$h[919].$h[920].$h[921].$h[922].$h[923].$h[924].$h[925]; 
Esto esta perfecto, funciona de maravillas... lo que hago luego de tomar estos caracteres (que solo tomo los valores ascii de la cadena), los paso a como floatente de la siguiente manera:

Código PHP:
function comaFlotante($val){
    
$entero hexdec($val);
    
$ascci pack('i'$entero);
    
$float unpack('f'$ascci);

return 
$float[1];
}

$matriz comaFlotante($matriz);
$montecaseros comaFlotante($montecaseros);
$norte comaFlotante($norte);
$sur comaFlotante($sur);
$setPoint comaFlotante($setPoint);
$error comaFlotante($error); 
y listo, esto luego lo guardo en un tabla en mi base de datos...

pero ahora tengo que hacer la inversa para uno de esos datos y es el "setpoint"

O sea... tengo que escribir en un archivo llamado setpoint.txt los valores ascii para que un PLC los lea...

Por ejemplo el usuario escribe en un campo : 40,5 o tambien 40 o cualquier numero decimal...

Esto lo tengo que llevar a la misma conversion ascii que lei al principio... entonces este es mi dilema...

Espero que me hayas entendido....
  #11 (permalink)  
Antiguo 04/10/2010, 08:47
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

Pues invierte la función de comaFlotante
Código PHP:
Ver original
  1. function flotante2Hex($val){
  2.     $pack = pack('f', $val);
  3.     $unpack = unpack('i', $pack);
  4.     $dechex = dechex($unpack[1]);
  5.     return strtoupper($dechex);
  6. }
  7.  
  8. $matriz = flotante2Hex($matriz); //43BE169B
  9. $montecaseros = flotante2Hex($montecaseros); //2A44F520
  10. $norte = flotante2Hex($norte); //65672053
  11. $sur = flotante2Hex($sur); //20536161
  12. $setPoint = flotante2Hex($setPoint); //204E6F72

También te recomiendo que uses la función substr
Código PHP:
Ver original
  1. $h = ascii2hex($read);
  2. $matriz = substr($h, 0, 8); //43BE169B
  3. $montecaseros = substr($h, 40, 8); //2A44F520
  4. $norte = substr($h, 116, 8); //65672053
  5. $sur = substr($h, 152, 8); //20536161
  6. $setPoint = substr($h, 84, 8); //204E6F72
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #12 (permalink)  
Antiguo 04/10/2010, 12:20
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Convertir Numeros a Caracteres ASCII

Hola,

Cita:
Iniciado por abimaelrc Ver Mensaje
¿Existe un valor 00 en el ASCII? Me gustaría saberlo.
La tabla ASCII se compone de 256 caracteres, desde el 0 (NULL) hasta el 255. Normalmente en casi todos los sistemas de computación el ordinal 0 en ASCII se usa para denotar NULL, como en C/C++.

Cita:
Iniciado por cmarrero Ver Mensaje
El tema es que no funcionaria con un coma flotante.. por ejemplo.. el numero 40 en coma flotante es 5.6051938572993E-44 ...
Creo que tienes que investigar un poco más sobre matemáticas. El número 40 en coma flotante es 40.0. O en el peor de los casos su representación exponencial 0.0000000000004e13 o 4.0e1, etc.

Cita:
Iniciado por cmarrero Ver Mensaje
... los paso a como floatente de la siguiente manera:

O sea... tengo que escribir en un archivo llamado setpoint.txt los valores ascii para que un PLC los lea...
Si quieres que el PLC los lea correctamente tienes que dejar afuera de la ecuación las operaciones de punto flotante. Las operaciones de punto flotante tienen un límite de exactitud. El código '00' del que hablaste al principio se podría interpretar como 2 bytes (16 bits) con un rango de 65535, con números más grandes las operaciones serán bastante inexactas.

Saludos,
  #13 (permalink)  
Antiguo 04/10/2010, 12:29
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Convertir Numeros a Caracteres ASCII

@HackmanC, es cierto, pero a lo que me refería no es al 0 solamente, sino al 00. Es que son dos caracteres, como él había indicado que no quería que saliera 4848 sino como un solo caracter.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #14 (permalink)  
Antiguo 04/10/2010, 12:50
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Convertir Numeros a Caracteres ASCII

Hola abimaelrc,

Cita:
Iniciado por abimaelrc Ver Mensaje
@HackmanC, es cierto, pero a lo que me refería no es al 0 solamente, sino al 00. Es que son dos caracteres, como él había indicado que no quería que saliera 4848 sino como un solo caracter.


Tienes toda la razón, es una cosa de interpretación, pero realmente así tuviste la oportunidad de aclararlo, porque creo que cmarrero le anda dando vueltas a algo que es mucho mas simple pero no lo ha comprendido bien. La tabla ASCII solamente puede representar códigos de 1 solo caracter, es decir solo del 0 al 255, tratar de interpretar el 4848 no se puede en ASCII, se sale del rango 0..255 (1 byte, 8 bits, 0xFF).

Solamente quería hacer esas aclaraciones, porque me pareció que no se ha dado en entender bien que es exactamente lo que quiere hacer, el problema me parecía simple hasta que metió los flotantes que no se que tienen que ver con todo el asunto, trabajar la tabla ASCII en flotante me parece ... como decirlo ... mal.

Saludos,
  #15 (permalink)  
Antiguo 04/10/2010, 13:55
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Exclamación Respuesta: Convertir Numeros a Caracteres ASCII

Muchisimas gracias por el aprote a todos, voy a tratar de explicar un poco por que todo este lio con los ascii, como flotantes y demas...

Anterior mente copie las siguientes lineas que leo desde un archivo que es escrito por un PLC, utilizo el programa Step 7 para leer los valores en formato "humano".

y por ejemplo...

niveles.log:
C±Ij L/segMontecs QC*t/ L/segSet Point QBH% Norte QDŒ^õ L/seg Sur QDá1< L/seg Saavedra Qmts Sarramea Qmts Error CONTACTOR 1 Error CONTACTOR 2 Corrig. MontecaserosCorrig. Alto Verde Corrigiendo caudal, Error MAX IZQUIERDA Error MAX DERECHA Modo MANUAL Error excede los li_mites. Pase a MANUALPor Favor espere... Proximo error a cor_regir= Q@Ú§`

Si vemos todo este codigo, vemos por ejemplo el primer valor a interpretar en ASCII..
"C±Ij" esto en comafloatente redondeado es algo asi como 355..

Bien ahora ese numero 355 que podemos interpretar es el nivel que tiene un canal...


Bien asi de simple... ahora como puse antes, el valor ascii mencionado anteriormente primero lo convierto a Hexadecimal y luego lo convierto a comaflotante asi obtengo el numero que deseo...

Pero el tema esta en hacer la inversa, tomar el valor decimal, comvertirlo a coma flotante luego a hexadecimal y luego a ascii para guardarlos en un archivo que el PLC lea...

Puse lo de que 5.6051938572993E-44 era igual a 40, por que fue la prueba que hice con la funcion que abimaelrc me sugirio... entonces si esto es incorrecto la funcion esta mal o no hace lo que deberia hacer....

Aca es en donde estoy perdido.. y lo admito, las matemáticas me cuestan, aunque me encantan... gracias por la ayuda
  #16 (permalink)  
Antiguo 04/10/2010, 20:08
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Convertir Numeros a Caracteres ASCII

Hola,

Cita:
Iniciado por cmarrero Ver Mensaje
Si vemos todo este codigo, vemos por ejemplo el primer valor a interpretar en ASCII..
"C±Ij" esto en comafloatente redondeado es algo asi como 355..

Bien ahora ese numero 355 que podemos interpretar es el nivel que tiene un canal...
Todavía no logro ver como esa serie de 4 bytes significa 355 en float. Cuando interpreto 'C┬▒I' dentro de un float no me da 355 ni cerca de ninguna forma, posiblemente es algo de interpretación de nuevo. Los float en la arquitectura de 32 bits se almacenan en 4 bytes.

Cita:
Iniciado por cmarrero Ver Mensaje
Bien asi de simple... ahora como puse antes, el valor ascii mencionado anteriormente primero lo convierto a Hexadecimal y luego lo convierto a comaflotante asi obtengo el numero que deseo...

Pero el tema esta en hacer la inversa, tomar el valor decimal, comvertirlo a coma flotante luego a hexadecimal y luego a ascii para guardarlos en un archivo que el PLC lea...
Veamos, solamente lo voy a mostrar con los primeros 4 bytes 'C┬▒I'.
Primero vamos a leer el archivo completo y mostramos los primeros 4 bytes 'C┬▒I'.
Código:
$data = file_get_contents('data.bin');
echo substr($data, 0, 4);
echo "\n";
Seguidamente convertimos en hexadecimal todo el archivo, y mostramos los primeros 8 caracteres que significan los 4 bytes en hexadecimal,
Código:
$datb = bin2hex($data);
$tempa = substr($datb, 0, 8);
echo $tempa;
echo "\n";
Ahora en $datb tienes todo el archivo en formato hexadecimal con el nibble alto primero, el nibble son 4 bits. Ahora convertimos de nuevo e imprimimos el resultado, que debería ser igual,
Código:
$f = pack('H*', $tempa);
print_r ($f);
El resultado te debería mostrar algo así por consola:
Código:
C┬▒I
43c2b149
C┬▒I
Es decir, los primeros 4 caracteres del valor leido, seguidos de su representación hexadecimal y finalmente su representación desde los valores hexadecimales, igual al primero.

Cita:
Iniciado por cmarrero Ver Mensaje
Puse lo de que 5.6051938572993E-44 era igual a 40, por que fue la prueba que hice con la funcion que abimaelrc me sugirio... entonces si esto es incorrecto la funcion esta mal o no hace lo que deberia hacer....
De nuevo creo que posiblemente es una cosa de interpretación,

Saludos,
  #17 (permalink)  
Antiguo 04/10/2010, 20:14
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Convertir Numeros a Caracteres ASCII

Hola,

Aparte si en algún momento necesitas usar el número como float, entonces tienes que hacer un pseudo-cast, con los datos originales. Posiblemente algo así:

$f = pack('H*', $tempa);
$f = unpack('f', $f);
print_r ($f); // $f[0] debería contener el valor de los primeros 4 bytes en float.

Saludos,
  #18 (permalink)  
Antiguo 05/10/2010, 07:26
(Desactivado)
 
Fecha de Ingreso: enero-2008
Ubicación: Mendoza
Mensajes: 458
Antigüedad: 16 años, 10 meses
Puntos: 2
Exclamación Respuesta: Convertir Numeros a Caracteres ASCII

Muchas gracias por la ayuda HackmanC..

Ahora te voy a colocar todo lo que hago con las funciones y los resultados, para que veas cuales son las interpretaciones que hago..

Código PHP:
<?php
$fp 
fopen('niveles.log','rb');
$read fread($fp,463);
fclose($fp);
//Archivo sin convertir
echo 'Archivo sin convertir:<br />';
echo 
$read;
echo 
'<br />';

function 
asciiToHex($ascii) {
    
$hex '';
    for (
$i 0$i strlen($ascii); $i++) {
    
$byte strtoupper(dechex(ord($ascii{$i})));
    
$byte str_repeat('0'strlen($byte)).$byte;
    
$hex.=$byte."";
    }
return 
$hex;
}
//Tomo los valores y los convierto a Hexadecimal
$h asciiToHex($read);
//Archivo Completo
echo 'Archivo completo en hexadecimal:<br />';
echo 
$h;
echo 
'<br />';
echo 
'Fracmentos que debo tomar:<br />';
$matriz $h[0].$h[1].$h[2].$h[3].$h[4].$h[5].$h[6].$h[7];
echo 
'Matriz: '.$matriz;
echo 
'<br />';
$montecaseros $h[40].$h[41].$h[42].$h[43].$h[44].$h[45].$h[46].$h[47];
echo 
'Montecaseros: '.$montecaseros;
echo 
'<br />';
$norte $h[116].$h[117].$h[118].$h[119].$h[120].$h[121].$h[122].$h[123];
echo 
'Norte: '.$norte;
echo 
'<br />';
$sur $h[152].$h[153].$h[154].$h[155].$h[156].$h[157].$h[158].$h[159];
echo 
'Sur: '.$sur;
echo 
'<br />';
$setPoint $h[84].$h[85].$h[86].$h[87].$h[88].$h[89].$h[90].$h[91];
echo 
'setPoint: '.$setPoint;
echo 
'<br />';
$error $h[918].$h[919].$h[920].$h[921].$h[922].$h[923].$h[924].$h[925];
echo 
'Error: '.$error;
echo 
'<br />';

//Ahora convierto a coma Flotante todos los datos hexadecimales que tome anteriormente
function hexa2float($val){
    
$entero hexdec($val);
    
$ascci pack('i'$entero);
    
$float unpack('f'$ascci);

return 
$float[1];
}

$matriz hexa2float($matriz);
echo 
'Matriz: '.$matriz;
echo 
'<br />';
$montecaseros hexa2float($montecaseros);
echo 
'Montecaseros: '.$montecaseros;
echo 
'<br />';
$norte hexa2float($norte);
echo 
'Norte: '.$norte;
echo 
'<br />';
$sur hexa2float($sur);
echo 
'Sur: '.$sur;
echo 
'<br />';
$setPoint hexa2float($setPoint);
echo 
'setPoint: '.$setPoint;
echo 
'<br />';
$error hexa2float($error);
echo 
'Error: '.$error;
echo 
'<br />';


//Ahora redonde los numeros para tener los valores mas claros
echo 'Matriz: '.round($matriz);
echo 
'<br />';
echo 
'Montecaseros: '.round($montecaseros);
echo 
'<br />';
echo 
'Norte: '.round($norte);
echo 
'<br />';
echo 
'Sur: '.round($matriz);
echo 
'<br />';
echo 
'setPoint: '.round($setPoint);
echo 
'<br />';
echo 
'Error: '.round($error);
echo 
'<br />';


//Ahora supongamos que el siguiente numero viene por POST de un form.
$setPoint '40.5';
echo 
'Set Point: '.$setPoint;
echo 
'<br />';

//paso este valor a Hexadecimal para hacer el mismo paso de conversiones que hice anterioremente
function flotante2Hex($val){ 
    
$pack pack('f'$val);
    
$unpack unpack('i'$pack);
    
$dechex dechex($unpack[1]);
    return 
strtoupper($dechex); 
}

$setPoint flotante2Hex($setPoint);
echo 
'Set Point: '.$setPoint;
echo 
'<br />';
//Ahora paso de Hexadecimal a Ascii
function hex2ascii($hex){
    
$ascii='';
    for(
$i=0$i<strlen($hex); $i=$i+2) {
        
$ascii.=chr(hexdec(substr($hex$i2)));
    }
    return(
$ascii);
}
//Ascii del Hexadecimal
$setPoint hex2ascii($setPoint);
echo 
'Set Point: '.$setPoint;
echo 
'<br />';
?>


Y todo esto me resuelve por ejemplo:

Archivo sin convertir:
F oC L/segMontecs QE„!Ñ L/segSet Point QB<% Norte QE$€- L/seg Sur QD¼'% L/seg Saavedra Qmts Sarramea Qmts Error CONTACTOR 1 Error CONTACTOR 2 Corrig. MontecaserosCorrig. Alto Verde Corrigiendo caudal, Error MAX IZQUIERDA Error MAX DERECHA Modo MANUAL Error excede los li_mites. Pase a MANUALPor Favor espere... Proximo error a cor_regir= QÀ˜¬
Archivo completo en hexadecimal:
460C6F43204C2F7365674D6F6E74656373200051458421D120 4C2F73656753657420506F696E74201951423C000025202020 4E6F7274652000514524802D204C2F73656720205375722000 5144BC2725204C2F7365672020202053616176656472612000 51000000006D7473202053617272616D656120005100000000 6D747320204572726F7220434F4E544143544F522031202020 4572726F7220434F4E544143544F5220322020202020202020 20202020202020202020202020202020202020202020202020 20202020202020202020202020202020202020202020202020 2020202020436F727269672E204D6F6E746563617365726F73 436F727269672E20416C746F20566572646520202020202020 202020202020202020202020202020436F7272696769656E64 6F2063617564616C2C204572726F72204D415820495A515549 45524441204572726F72204D41582044455245434841202020 202020204D6F646F20204D414E55414C202020204572726F72 20657863656465206C6F73206C695F6D697465732E20506173 652061204D414E55414C506F72204661766F72206573706572 652E2E2E2050726F78696D6F206572726F72206120636F725F 72656769723D200051C098AC00
Fracmentos que debo tomar:
Matriz: 460C6F43
Montecaseros: 458421D1
Norte: 4524802D
Sur: 44BC2725
setPoint: 423C0000
Error: C098AC00
Matriz: 8987.8154296875
Montecaseros: 4228.2270507812
Norte: 2632.0109863281
Sur: 1505.2232666016
setPoint: 47
Error: -4.77099609375
Matriz: 8988
Montecaseros: 4228
Norte: 2632
Sur: 8988
setPoint: 47
Error: -5
Set Point: 40.5
Set Point: 42220000
Set Point: B"



Mi pregunta ahora, es si esto esta bien, y si un numero de coma flotante tiene 4 bytes, por que cuando a este numero lo guardo en un archivo txt me queda de 1 byte o 2 bytes...

Saludos
  #19 (permalink)  
Antiguo 05/10/2010, 12:30
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Convertir Numeros a Caracteres ASCII

Hola,

Cita:
Iniciado por cmarrero Ver Mensaje
Mi pregunta ahora, es si esto esta bien, y si un numero de coma flotante tiene 4 bytes, por que cuando a este numero lo guardo en un archivo txt me queda de 1 byte o 2 bytes...
Internamente la computadora no guarda los números flotantes como nosotros los miramos, el valor 40.5 lo guarda en formato binario con 32 dígitos binarios (0/1). Normalmente se usan 4 bytes para los flotantes en la arquitectura de 32 bits, pero depende del hardware y el software. En PHP en x86 de 32 bits son 4.

Posiblemente (si sabes lenguaje C) esto resuelva tu duda,
Acá intenté explicar como se almacena un float en la memoria:
http://www.forosdelweb.com/f96/conve...inaria-738518/

Cita:
Iniciado por cmarrero Ver Mensaje
... Ahora te voy a colocar todo lo que hago con las funciones y los resultados, para que veas cuales son las interpretaciones que hago..
Yo simplifique un poco el código que pusiste solamente para probar, posiblemente te sea de utilidad:

Código PHP:
<?php

$fp 
fopen('niveles.log','rb');
$read fread($fp,463);
fclose($fp);
$h strtoupper(bin2hex($read));

echo <<<EOF
Archivo sin convertir:<br />$read<br />
Archivo completo en hexadecimal:<br />$h<br />
Fracmentos que debo tomar:<br />
EOF;

function 
show($datos) {
    echo <<<EOF
    Matriz: $datos[matriz]<br />
    Montecaseros: $datos
[montecaseros]<br />
    Norte: $datos
[norte]<br />
    Sur: $datos
[sur]<br />
    setPoint: $datos
[setPoint]<br />
    Error: $datos
[error]<br />
EOF;
}

function 
hexa2float($val) {
    
$a hexdec($val);
    
$b pack('i'$a);
    
$c unpack('f'$b);
    return 
$c[1];
}

$datos1 = Array(
    
'matriz' => substr($h08),
    
'montecaseros' => substr($h408),
    
'norte' => substr($h1168),
    
'sur' => substr($h1528),
    
'setPoint' => substr($h848),
    
'error' => substr($h9188)
);
show($datos1);

$datos2 = Array();
foreach (
$datos1 as $key => $val)
    
$datos2[$key] = hexa2float($val);
show($datos2);

$datos3 = Array();
foreach (
$datos2 as $key => $val)
    
$datos3[$key] = round($val);
show($datos3);


$f = (float)'40.5';
$g pack('f'$f);
echo 
$g;
?>
La función hexa2float la dejé así como la tenías porque creo que te funciona correctamente como lo necesitas, pero es una situación de interpretación, yo lo interpreto de otra forma porque no sé exactamente en que lo vas a usar, es decir yo puedo decir que está bien o mal según mi criterio nada mas.

Cita:
Iniciado por cmarrero Ver Mensaje
//Ahora supongamos que el siguiente numero viene por POST de un form.
$setPoint = '40.5';
echo 'Set Point: '.$setPoint;
echo '<br />';
En esta última parte creo que estas confundiendo el concepto de 'que es un número decimal (float) y que es un número en string que representa un número decimal. Para representar ese número en 'float' solo lo tienes que empaquetar en un float.

Código PHP:
$f = (float)'40.5';
$g pack('f'$f);
echo 
$g// El ASCII que representa el 40.5 en float en little endian.
//  "B 
Acá posiblemente existe un problema con el endianess, que significa el orden de los bytes, las computadoras guardan los float en 4 bytes en el x86 de 32 bits, pero los 2 primeros son los últimos en otras arquitecturas.

Saludos,

Etiquetas: ascii, caracteres, numeros
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 20:57.