Mapping float to ulong in CTFE

Petar Petar
Thu Dec 12 19:39:16 UTC 2019


On Thursday, 12 December 2019 at 19:21:22 UTC, berni44 wrote:
> Is it possible to get to the bits of a float in CTFE? I tried 
> the following, but this doesn't work:
>
> ```
> import std.stdio;
>
> union FloatBits
> {
>     float floatValue;
>     ulong ulongValue;
> }
>
> ulong test(float f)
> {
>     FloatBits fb;
>     fb.floatValue = f;
>     return fb.ulongValue;
> }
>
> void main()
> {
>     static assert(test(3.0) == 1077936128);
> }
> ```
>
> test.d(13): Error: reinterpretation through overlapped field 
> ulongValue is not allowed in CTFE
> test.d(18):        called from here: test(3.00000F)
> test.d(18):        while evaluating: static 
> assert(test(3.00000F) == 1077936128LU)

You can use a C-style pointer reinterpret cast like this:

uint test(float f) { return *cast(uint*)&f; }

Make sure that source and destination types have the same size.

Or more generally:

IntegerOfSize!T bitRepresentation(T)(T f)
{
     return *cast(IntegerOfSize!T*)&f;
}

pragma (msg, bitRepresentation(3.0f)); // 1077936128u
pragma (msg, bitRepresentation(3.0));  // 4613937818241073152LU

void main()
{
     static assert(bitRepresentation(3.0f) == 1077936128);
}

template IntegerOfSize(T)
{
     static if (T.sizeof == 1)
         alias IntegerOfSize = ubyte;
     else static if (T.sizeof == 2)
         alias IntegerOfSize = ushort;
     else static if (T.sizeof == 4)
         alias IntegerOfSize = uint;
     else static if (T.sizeof == 8)
         alias IntegerOfSize = ulong;
     else
         static assert(0);
}


More information about the Digitalmars-d-learn mailing list