Reputation: 6116
I want to save the value of a float variable named f
in the third element of an array named i
in a way that the floating point part isn't wiped (i.e. I don't want to save 1
instead of 1.5
). After that, complete the last line in a way that we see 1.5
in the output (don't use cout<<1.5;
or cout<<f;
or some similar tricks!)
float f=1.5;
int i[3];
i[2] = ... ;
cout<<... ;
Does anybody have any idea?
Upvotes: 1
Views: 6074
Reputation: 5072
Use type-punning with union
if they have the same size under a compilation environment:
static_assert(sizeof(int) == sizeof(float));
int castFloatToInt(float f) {
union { float f; int i; } u;
u.f = f;
return u.i;
}
float castIntToFloat(int i) {
union { float f; int i; } u;
u.i = i;
return u.f;
}
// ...
float f=1.5;
int i[3];
i[2] = castFloatToInt(f);
cout << castIntToFloat(i);
Using union
is the way to prevent aliasing problem, otherwise compiler may generate incorrect results due to optimization.
This is a common technique for manipulating bits of float directly. Although normally uint32_t
will be used instead.
Upvotes: 8
Reputation: 212969
If we can assume that int
is 32 bits then you can do it with type-punning:
float f = 1.5;
int i[3];
i[2] = *(int *)&f;
cout << *(float *)&i[2];
but this is getting into Undefined Behaviour territory (breaking aliasing rules), since it accesses a type via a pointer to a different (incompatible) type.
Upvotes: 2
Reputation: 1679
Generally speaking, you cannot store a float
in an int
without loss of precision.
You could multiply your number with a factor, store it and after that divide again to get some decimal places out of it.
Note that this will not work for all numbers and you have to choose your factor carefully.
float f = 1.5f;
const float factor = 10.0f;
int i[3];
i[2] = static_cast<int>(f * factor);
std::cout << static_cast<float>(i[2]) / factor;
Upvotes: 3