Nepho
Nepho

Reputation: 1112

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.

Upvotes: 0

Views: 341

Answers (1)

UnholySheep
UnholySheep

Reputation: 4096

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.

Upvotes: 1

Related Questions