runtime icon indicating copy to clipboard operation
runtime copied to clipboard

Bizarre decimal-to-double behavior difference on same machine, same code

Open cyanite opened this issue 9 months ago • 0 comments

Description

I made a dotnet class library with a single method:

public static double ConvertForMe(decimal d)
{
       return (double)d;
}

I then wrote a small console program that calls this, like this:

var dec = -4619.7403751459050600M;
var doubleDll = DoubleConversion.DoubleConversion.ConvertForMe(dec);
Console.WriteLine($"Decimal:   {dec}");
Console.WriteLine($"Double dll: {doubleDll}");.

I get:

Decimal:   -4619,7403751459050600
Double dll: -4619,740375145904

That's fine, I guess, and this can be reproduced on various machines and online dotnet playgrounds. However, on the same machine using the same, previously compiled, class library, but calling it from inside a larger .NET 8-based server we have running there in test, we instead get:

Decimal:   -4619,7403751459050600
Double dll: -4619,740375145905

Which amounts to a difference in the LSB in the Int64 representation of the double (using BitConverter). Since this is financial software, people are wondering about this, and I can't explain it. This only seems to happen on this particular machine (and only when invoked via our larger server, using Assembly.Load and IoC).

Reproduction Steps

As described above. We haven't been able to reproduce the abnormal result in any other contexts so far.

Expected behavior

The version ending in 4. Well, it's hard to say. I think the version ending in 5 seems more correct, but every other context, machine and online playground seems to give the one ending in 4.

Actual behavior

When we call the method in the dll from our (ultimately .NET 8 console program started as Windows service), we get the version ending in 5.

Regression?

No response

Known Workarounds

No response

Configuration

The problem happens on the same machine, but the environment is slightly different. Common environment variables that might influence this (but that are present both in the 4 and 5 case):

DOTNET_gcServer: 1

Environment variables unique to the case where we get the abnormal behavior:

COMPlus_ReadyToRun: 0
CORECLR_ENABLE_PROFILING: 1
CORECLR_PROFILER: {some guid}
CORECLR_PROFILER_PATH_64: some-path-to-dynatrace/.../oneagentloader.dll

I have tried to manually set the COMPlus variable but it doesn't reproduce the abnormal behavior. I haven't investigated if the tracing can be related.

Other configuration: .NET 8.0.2 Microsoft Windows 10.0.14393

Other information

No response

cyanite avatar May 13 '24 10:05 cyanite