0

So far i have this working outside of a switch statement but i really want to switch on a const float.

typedef union IntAndFloat
{
    float fvalue;
    uint32_t uivalue;
    int32_t ivalue;
};

constexpr uint32_t FloatToIntImpl(const IntAndFloat value) { return value.uivalue; }
constexpr uint32_t FloatConst(const float value) { return FloatToIntImpl({value});  }

int main()
{
    cout << FloatConst(1.0f) << endl;
    switch(0x3f800000)
    {
        case FloatConst(1.0f): cout << "hit" << endl; break;
    }

//example 2

//ugly version
int val = 0x3f800000;
switch (val)
{
    case 0xbf800000: cout << "-1" << endl; break;
    case 0x80000000://neg 0
    case 0x00000000: cout << "0" << endl; break;
    case 0x3f800000: cout << "1" << endl; break;
    case 0x40000000: cout << "2" << endl; break;
    case 0x40400000: cout << "3" << endl; break;
    case 0x40800000: cout << "4" << endl; break;
    case 0x40A00000: cout << "5" << endl; break;
    case 0x40C00000: cout << "6" << endl; break;
    case 0x40E00000: cout << "7" << endl; break;
    default: cout << IntToFloat(val) << endl;

}

//clean nice looking version
int val = FloatConst(1f);
switch (val)
{
    case FloatConst(-1f): cout << "-1" << endl; break;
    case FloatConst(-0f)://neg 0
    case FloatConst(0f): cout << "0" << endl; break;
    case FloatConst(1f): cout << "1" << endl; break;
    case FloatConst(2f): cout << "2" << endl; break;
    case FloatConst(3f): cout << "3" << endl; break;
    case FloatConst(4f): cout << "4" << endl; break;
    case FloatConst(5f): cout << "5" << endl; break;
    case FloatConst(6f): cout << "6" << endl; break;
    case FloatConst(7f): cout << "7" << endl; break;
    default: cout << IntToFloat(val) << endl;
}

}

On building in gcc you get:

error: accessing 'IntAndFloat::uivalue' member instead of initialized 'IntAndFloat::fvalue' member in constant expression

I don't know of any other way of doing it other then.

inline uint32_t FloatToUInt(float x) { return *(uint32_t*)&x; }

However that isnt constant.

I'm not even sure if this is possible and if it's not it should be.

  • Please explain exactly what you are trying to do? – DisappointedByUnaccountableMod Oct 10 '16 at 05:08
  • Comparing exact floating point values, except when they're exact integers, is a recipe for bugs. Usually. Simply ditch the idea of a `switch`. – Cheers and hth. - Alf Oct 10 '16 at 05:09
  • It is simply to add to the readability of simple code of switching on constant whole floats. – Native Function Oct 10 '16 at 05:12
  • 1
    You're breaking aliasing rules, so the behavior is undefined. If you want to read the bits of a float as an int, the only "portable" way is to memcpy the bytes from one into the other (portable in quotes because now the sizes need to match, the resulting value doesn't trap, etc.). No clue if you can construct a constexpr `memcpy` or equivalent. – GManNickG Oct 10 '16 at 05:13
  • type punning through unions is only valid in C, not C++: http://stackoverflow.com/questions/25664848/unions-and-type-punning – Simon Byrne Oct 12 '16 at 11:56

0 Answers0