Ebrahim Ghasemi
Ebrahim Ghasemi

Reputation: 6116

Save a float into an integer without losing floating point precision

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

Answers (3)

Milo Yip
Milo Yip

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

Paul R
Paul R

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.

LIVE DEMO

Upvotes: 2

Beta Carotin
Beta Carotin

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

Related Questions