Closed
Description
Conversions from UInt64
to Double
for values greater than long.MaxValue
are currently incorrect. The same issue may exist for UInt32
to Double
for values greater than int.MaxValue
but I have not confirmed.
The simple repro case is detailed here: dotnet/csharplang#4074
using System;
namespace App
{
internal static class Program
{
internal static void Main()
{
/// Displays 'True'.
Console.WriteLine(10648738977740919977d != 10648738977740919977);
}
}
}
You can see approximately what the runtime generates by looking at: https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWzQBMQBqAHwAEAmARgFgAoSgZgAIa2BhNgbybaCO7IhACuwADYw2AWQAUYyRAB2AczYIAlHwFD9lAOyaA3HsEBfJhaA===
public double M(ulong x) {
return x;
}
Which results in:
L0000: vzeroupper
L0003: vxorps xmm0, xmm0, xmm0
L0007: vcvtsi2sd xmm0, xmm0, rdx
L000c: test rdx, rdx
L000f: jge short L0019
L0011: vaddsd xmm0, xmm0, [C.M(UInt64)]
L0019: ret
The constant used by L0011
appears to be 1.8446744073709552E+19
(0x43f0000000000000
)
category:correctness
theme:optimization
skill-level:beginner
cost:small
impact:small
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done