digitalmars.D.learn - Mapping float to ulong in CTFE
- berni44 (25/25) Dec 12 2019 Is it possible to get to the bits of a float in CTFE? I tried the
- Petar Kirov [ZombineDev] (28/53) Dec 12 2019 You can use a C-style pointer reinterpret cast like this:
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)
Dec 12 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); }
Dec 12 2019
On Thursday, 12 December 2019 at 19:39:16 UTC, Petar Kirov [ZombineDev] wrote: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.Hey, great! :-)
Dec 13 2019
Yeah, it worked (at least for %a): static assert(format!"%.3a"(1.0f) == "0x1.000p+0");
Dec 13 2019