Float values are wrong in union

jkpl via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 21 22:02:41 PDT 2016


On Monday, 22 August 2016 at 04:52:40 UTC, Cauterite wrote:
> On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
>> I made a union to convert between int bits and floats, but the 
>> values are coming out wrong sometimes.
>
> I can already tell what this is going to be...
> The problem is almost certainly nothing to do with your union, 
> it's this line:
>> float t2 = t.f;
> This will load 0x7fb00000 into ST(0), which instantly converts 
> it to 7FF00000 because it's a signalling NaN, then store ST(0) 
> in your float `t2`.
>
> Signalling NaNs are an ongoing problem in D's codegen. See 
> Don's remarks at this page: 
> https://issues.dlang.org/show_bug.cgi?id=16105#c2
>
> The reason it works in other languages is because they don't 
> place floats in the floating point registers for non-arithmetic 
> operations. I've been trying to patch DMD's backend to behave 
> this way too, but it's much harder than I expected (difficult 
> codebase to understand/navigate).

That's a 32 bit codegen issue then because DMD64 's disasm shows 
that SSE regs are used:

====
void foo()
{
     union test { int i; float f; }
     test t = { i : 0x7fb00000};
     float t2 = t.f;
     test t3 = { f : t2 };
}
===

yields to

===
00000000004586D0h  push rbp
00000000004586D1h  mov rbp, rsp
00000000004586D4h  sub rsp, 10h
00000000004586D8h  mov dword ptr [rbp-10h], 7FB00000h
00000000004586DFh  movss xmm0, dword ptr [rbp-10h]
00000000004586E4h  movss dword ptr [rbp-0Ch], xmm0
00000000004586E9h  movss xmm1, dword ptr [rbp-0Ch]
00000000004586EEh  movss dword ptr [rbp-08h], xmm1
00000000004586F3h  leave
00000000004586F4h  ret
===


More information about the Digitalmars-d-learn mailing list