简体   繁体   中英

Read an uint32 as a float without overflow?

I'm working on a program that does that kind of things : it takes an array of float values, and encodes the values three by three in a base64 string. When the whole array is encoded, if there are some values left (number < 3), it encodes them and adds the necessary '=' (for more informations, see here ).

Anyway, here is not the problem. My problem is that, at the very beginning of this base64 string, I need to indicate the number of floats following, but as an uint32. However, I'm forced to use my function using floats... So I have to use a hack, and initialize a pointer to an uint32, but read it as a float.

Here is how I do it:

uint32_t *ivalue = (uint32_t *)malloc(sizeof (uint32_t));
float *fvalue = (float *)ivalue;
// (...) some code
*ivalue = 2 * sizeof (float); // The value I want, 2 * 4 in this case (on my computer)
tempoCoor.push_back(*fvalue);

tempoCoor is a std::vector I fill, and when the size is 3, I encode its content and empty it.

However, there is a problem with my hackish method... When I compute values smaller than 256 (I think this is this value), everything is fine, but not when my values are greater or equal than 256. Why is that ? How could I fix it ?

If I was not clear in any way, please ask me more details. I can explain more if needed.

Ok, so here some explanations on what is wrong with that code:
1. Why are you using malloc in C++? It is a bad habit and only in some few special cases appropriate. Use new instead! (Also don't cast malloc [in C] or at least use C++ casts)
2. Why are you even allocating memory on the heap? it seems completely unnecessary in this case.
3. Don't use C-Style casts in C++ code - C++ casts ( static_cast , etc.) are safer and contain some error checking.

So here is how this code might look like.

uint32_t ivalue = 2 * sizeof(float); //simply assigning the value  
// ... some Code
tempoCoor.push_back(static_cast<float>(ivalue)); //using proper C++ cast to convert

As you were using memory on the heap and accessing it directly, by reinterpreting a pointer (which would be equivalent to reinterpret_cast ) you are using the data which was written there as if it was a float, which it obviously wasn't. Once your values got big enough some of the bits were interpreted as being part of the exponent and you received wrong values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM