2009-05-05 9 views
6

¿Cuál es la mejor forma de convertir una matriz de caracteres sin signo a una matriz de elementos flotantes en C++?Transmisión de una matriz de caracteres sin signo a una matriz de flotantes

actualmente I tienen un bucle como sigue

for (i=0 ;i< len; i++) 
    float_buff[i]= (float) char_buff[i]; 

También necesito invertir el procedimiento, es decir, convertir de unsigned char a flotar (float a la conversión de 8 bits)

for (i=0 ;i< len; i++) 
    char_buff[i]= (unsigned char) float_buff[i]; 

Cualquier consejo sería ser apreciado

Gracias

+1

¿Qué estás haciendo que lo requiera? –

Respuesta

2

Su solución parece bien, aunque en el camino de regreso, podrías perder los dígitos flotantes en el lanzamiento.

+0

Gracias No estoy seguro de qué molde de estilo C++ utilizar (reinterpretar o estático), así que acabo de utilizar el viejo estilo, Cualquier idea. Además, lo que sucede al convertir de flotante a char sin signo si el flotante es mayor que 255.0. (no está preocupado por los dígitos después del punto) Gracias –

+0

En caso de que el flotador sea más grande que 255, tendrá el resultado MOD después del lanzamiento (igual que con cualquier otro desbordamiento). Por ejemplo: float = 500 -> char = 254. float = 256 -> char = 0. Por cierto, aquí hay información sobre static_cast: http://stackoverflow.com/questions/103512/in-c-why-use-staticcastintx -instead-of-intx –

+0

El comportamiento si el valor flotante es> = 256 no está definido; obtener un valor de módulo bien podría ser común, pero no está garantizado. –

2

¿Para qué lo hace? Mover un flotador en un char no tiene sentido. En la mayoría de las plataformas, un flotante tendrá 4 bytes y representará un número de coma flotante, donde como char será 1 byte y a menudo representa un solo carácter. Perderás 3 bytes de datos tratando de meter un flotador en un char, ¿verdad?

+0

Gracias Necesito convertir de flotador a 8bit –

+0

El elenco realizará una conversión, truncando la porción fraccionaria del flotador. Esto puede ser exactamente lo que quiere la persona. Una cosa clave a tener en cuenta es que si la parte integral del flotante no se puede representar en un char sin signo (generalmente si no está en el rango 0-255) no está definido. –

+0

Gracias Michael, no me importa perder la parte fraccionaria. Si el flotador es inferior a 255, ¿funcionará el molde? Iba a fijar el resultado en 255 si el flotador era mayor que este. Gracias –

8

Su solución es más o menos la mejor opción, sin embargo, me gustaría considerar el cambio a:

char_buff[i]= static_cast<unsigned char>(float_buff[i]); 
0

Si usted está tratando con matrices muy grandes y el rendimiento es esencial a continuación, lo siguiente puede resultar ligeramente más eficiente:

float *dst = float_buff; 
    unsigned char *src = char_buff; 

    for (i=0; i<len; i++) *dst++ = (float)*src++; 
+0

Gracias Dan, aprecia la sugerencia –

+0

O std :: copy (char_buff, char_buff + len, float_buff); –

+0

El uso de std :: copy aquí expone un error en STL (así como en C++). Cuando haces una copia de algo, debería ser cierto que copie == original. Al confiar en el casting implícito, esto ya no es cierto, por lo que debe evitarse la conversión implícita. –

2

Su primer bucle no requiere un lanzamiento. Puede convertir implícitamente de un tipo (por ejemplo, unsigned char) a un tipo más amplio (por ejemplo, float). Su segundo bucle debe utilizar static_cast:

for (i=0; i< len; i++) 
    char_buff[i]= static_cast<unsigned char>(float_buff[i]); 

Utilizamos static_cast indicar explícitamente al compilador para hacer la conversión a un tipo más estrecho. Si no usa el molde, su compilador podría advertirle que la conversión podría perder datos. La presencia del operador de elenco significa que usted comprende que puede perder precisión en los datos y que está de acuerdo. Esto es no un lugar apropiado para usar reinterpret_cast. Con static_cast, al menos tiene algunas restricciones sobre las conversiones que puede hacer (por ejemplo, probablemente no le permita convertir un Bird* en un Nuclear_Submarine*). reinterpret_cast no tiene tales restricciones.

Además, esto es lo que Bjarne Stroustrup tiene para decir sobre este tema.

9

Creo que la mejor manera es utilizar un objeto función:

template <typename T> // T models Any 
struct static_cast_func 
{ 
    template <typename T1> // T1 models type statically convertible to T 
    T operator()(const T1& x) const { return static_cast<T>(x); } 
}; 

seguido de:

std::transform(char_buff, char_buff + len, float_buff, static_cast_func<float>()); 
std::transform(float_buff, float_buff + len, char_buff, static_cast_func<unsigned char>()); 

Ésta es la más legible porque dice lo que se está haciendo en Inglés: la transformación de una secuencia en un tipo diferente usando fundición estática. Y los moldes futuros se pueden hacer en una línea.

1

El elenco es automático, por lo que no es necesario que sea explícito.
Pero se pueden utilizar los algoritmos estándar:

std::copy(char_buff,char_buff+len,float_buff); 

Conversión de vuelta de flotación a CHAR hay una pérdida potencial de información. Entonces debes ser más explícito.

std::transform(float_buff,float_buff+len,char_buff,MyTransform()); 

Aquí se utiliza la clase MyTransform que debe tener un operador() que toma un flotador y devuelve un char. Eso debería ser trivial para implicar.

0

Nadie ha mencionado esto, pero si usted está haciendo cualquier aritmética con los flotadores, es posible que desee redondear en lugar de truncar ... si tiene el carbón 49, y se excita en 4.9E1, después de algún aritmética, podría convertirse en 4.89999999E1 que se convertirá en 48 cuando lo vuelva a convertir en un char.

Si no está haciendo nada con el flotador, esto no debería ser un problema, pero ¿por qué lo necesita como un flotador en primer lugar?

Cuestiones relacionadas