1

I have a 4byte hex number, when I convert it to float it is -0.5(I checked references and it's correct), but printf gives very wrong value:

 int f=0xBF000000; printf("%f",(float)f); // prints -1090519040.000000 

I can't figure out what is wrong here! All calculators give the correct value as -0.5, but printf gives above value.

2
  • 9
    But 0xBF000000 == -1090519040. Are you having trouble understanding how signed integers work? **(Edit: Oh wait. Perhaps you meant printf("%f",*(float*)(&f));) Commented Jun 21, 2018 at 8:42
  • 6
    A cast from integer to floating point does not just reinterpret the values from memory. It converts the numeric value. Commented Jun 21, 2018 at 8:43

2 Answers 2

13

Your int has the value -1090519040. If you print it you get this value:

printf("%d", f); // -1090519040 

If you typecast it to float, it will take this value and change the type but not the value. So it will result in -1090519040.0000.

If you actually want to interpret your int as a float, you can use a pointer:

float* p = &f; printf("%f",*p); // -0.500000 

Here you have a float pointer that points to the address of your integer and if you print it it will interpret the bits as a float.

Comment from Eric Postpischil:

float *p = &f; is not a proper way to reinterpret the bytes of an object in C, as it violates the aliasing rule (C 2011 [N1570] 6.5 7, an object’s value shall be accessed only through its effective type, a character type, or certain others).

Another (better) way would be to use memcopy and copy your int into another float:

int a = 0xBF000000; float b = 0; memcpy(&b, &a, 4); printf("%f", b); // -0.500000 
Sign up to request clarification or add additional context in comments.

4 Comments

Actually even worse. The value of the constant is 3204448256 and it is implementation defined to which value this is converted if it doesn't fit into an int. C has no negative constants.
float *p = &f; is not a proper way to reinterpret the bytes of an object in C, as it violates the aliasing rule (C 2011 [N1570] 6.5 7, an object’s value shall be accessed only through its effective type, a character type, or certain others). Proper ways are to copy the bytes (as with the memcpy shown in this answer) or to reinterpret through a union (6.5.2.3 3).
@EricPostpischil I added your comment in my answer. Thanks.
All these examples are implementation dependent. What if floats are stored the normal way, but ints are big-endian.
1

If you like the access to every single Byte of your float-value you could use a union.

typedef union { struct { uint8_t Byte1; uint8_t Byte2; uint8_t Byte3; uint8_t Byte4; }; float_t FloatValue; } myFloatT; 

3 Comments

That works in practice but it is undefined/implementation defined what happens when you write a float_t to the union and then read the unit8_t.
@GoswinvonBrederlow There is no UB in your comment. Perhaps you are thinking of some other language than C?
en.cppreference.com/w/c/language/union: "If the member used to access the contents of a union is not the same as the member last used to store a value, the object representation of the value that was stored is reinterpreted as an object representation of the new type (this is known as type punning). If the size of the new type is larger than the size of the last-written type, the contents of the excess bytes are unspecified (and may be a trap representation)" It float_t is for example 24 bit then reading Byte4 is undefined. Always UB in c++.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.