Casting an array of unsigned chars to an array of floats

随声附和 提交于 2019-12-22 05:17:11

问题


What is the best way of converting a unsigned char array to a float array in c++?

I presently have a for loop as follows

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

I also need to reverse the procedure, i.e convert from unsigned char to float (float to 8bit conversion)

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

Any advice would be appreciated

Thanks


回答1:


I think the best way is to use a function object:

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); }
};

followed by:

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>());

This is the most readable because it says what is being done in English: transforming a sequence into a different type using static casting. And future casts can be done in one line.




回答2:


Your solution is pretty much the best option, however, I would consider switching to:

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



回答3:


Your solution seems right, though on the way back, you might lose the floating digits in the casting.




回答4:


For what purpose are you doing this? Shoving a float into a char doesn't really make sense. On most platforms a float will be 4 bytes and represent a floating point number, where as a char will be 1 byte and often represents a single character. You'll lose 3 bytes of data trying to shove a float into a char, right?




回答5:


Your first loop doesn't require a cast. You can implicitly convert from one type (e.g., unsigned char) to a wider type (e.g., float). Your second loop should use static_cast:

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

We use static_cast to explicitly tell the compiler to do the conversion to a narrower type. If you don't use the cast, your compiler might warn you that the conversion could lose data. The presence of the cast operator means that you understand you might lose data precision and you're ok with it. This is not an appropriate place to use reinterpret_cast. With static_cast, you at least have some restrictions on what conversions you can do (e.g., it probably won't let you convert a Bird* to a Nuclear_Submarine*). reinterpret_cast has no such restrictions.

Also, here's what Bjarne Stroustrup has to say about this subject.




回答6:


The cast is automatic so you don't need to make it explicit.
But you can use the standard algorithms:

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

Converting back from float to char there is a potential loss of information. So you need to be more explicit.

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

Here we use the class MyTransform which should have an operator() that takes a float and returns a char. That should be trivial to impliment.




回答7:


If you are dealing with very large arrays and performance is essential then the following may prove slightly more efficient:

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

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



回答8:


No one has mentioned this, but if you're doing any arithmetic with the floats, you may want to round instead of truncate... if you have the char 49, and it gets turned into 4.9E1, after some arithmetic, it might turn into 4.89999999E1 which will turn into 48 when you turn it back into a char.

If you're not doing anything with the float, this shouldn't be a problem, but then why do you need it as a float in the first place?



来源:https://stackoverflow.com/questions/825344/casting-an-array-of-unsigned-chars-to-an-array-of-floats

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!