Casting ((DWORD) 0xFFFFFFFF) to single precision float without changing binary value

2.6k views Asked by At

I want to compile a single precision float into flash as 0xFFFFFFFF (unitialized flash).

When I try (FLOAT32) ((UINT32) 0xFFFFFFFF), it converts to a floating point (0x0000804F) during the compilation process instead of 0xFFFFFFFF.

This applies to the initialization of a field in a struct in file scope. When I think of it, this means that the compiler is expecting a FLOAT32 literal.

I am beginning to wonder whether this is actually possible.

[EDIT: This applies to initialization of a field in a struct in file scope]

4

There are 4 answers

4
steveha On

In C, the best way is to use a union. Store into the UINT32 field, then read it out from the float field.

Complete discussion here: How to convert or cast a float into its bit sequence such as a long

Also, if you have C99 features available, you can use designated initializers to specify which of the union fields you want to assign. Even if you don't have C99 you can just make sure that the UINT32 fields in the union is the first one, so it will be assigned by default. http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

0
user694733 On

One solution may be to use absolute placement. It may or may not be possible with your tools.

Note: I have never done this and syntax here isn't probably even valid on any compiler. This is only an example of the intention.

UINT32 const i = 0xFFFFFFFF @ 0x12345678; /* Place i at address 0x12345678 */
extern FLASH32 const f @ 0x12345678;  /* Pretend that f is at the same address */
1
bkausbk On

I think using unions and then casting any type to it would work:

typedef union _DATA {
    UINT32 AsInteger;
    FLOAT AsFloat;
} DATA;

char* Buffer = malloc(...);
ReadFromFile(Buffer, 1000);

// Casting
// ((DATA*) (Buffer + Offset))->AsFloat
// ((DATA*) (Buffer + Offset))->AsInteger

Or statically

DATA MyData;
MyData.AsInteger = 0xffffffff;

// C99
DATA MyData = {.AsInteger = 0xffffffff};

// C
DATA MyData = {0xffffffff};
2
Bernd Elkemann On

As you request in the comment: here at non-block-scope (you can make global- or file-scope):

#include <inttypes.h>
#include <stdio.h>
typedef union {
    uint32_t uint32;
    float f;
} aliasing;
aliasing a = { 0xffffffff };
int main(){
    printf("%u %f\n", a.uint32, a.f); // output: 4294967295 -1.#QNAN0
    return 0;
}

Also, if you want it inside a struct (your original question) and still want static initialization you can do:

#include <inttypes.h>
#include <stdio.h>
typedef union {
    uint32_t uint32;
    float f;
} aliasing;
typedef struct {
    aliasing a;
    int otherstuff;
} thestruct_t;
thestruct_t thestruct = { { 0xffffffff }, 0 };
int main(){
    printf("%u %f\n", thestruct.a.uint32, thestruct.a.f); 
         // output: 4294967295 -1.#QNAN0
    return 0;
}