.Net内联数学调用在x64版本中生成无穷大

时间:2017-08-29 15:35:28

标签: .net x86 64-bit

我很好奇是否有其他人可以重现这个问题,或者这只是我的机器的问题。如果我在发布模式下在控制台应用程序中运行以下代码,并且未选中“项目属性”下的“首选32位”选项 - >构建,它返回无限。但是一旦我切换回更喜欢32位,它就会返回0.1。

class Program
{
    static void Main(string[] args)
    {
        TestClass t = new TestClass();
        t.Test(10);

        Console.ReadKey();
    }
}

public class TestClass
{
    public void Test(int logarithmBase)
    {
        double min = 0.9;
        Console.WriteLine(Math.Pow(logarithmBase, Math.Floor(Math.Log(min, logarithmBase))));
    }
}

至少对我而言,有趣的部分是,如果我将logarithmBase更改为double,则开始输出0.1。此外,如果我将数学字符串打断为单独的行,那么它也会输出0.1。

我可以通过做上面提到的事情之一来轻松解决这个问题,但如果有人解释为什么这样做会很棒!

编辑:这是IL反汇编程序对主要和测试功能的反汇编,并且未选中“在模块加载时抑制JIT优化”。我对32位和64位版本的IL进行了比较,看起来与我能说的完全相同。

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size       19 (0x13)
.maxstack  8
IL_0000:  newobj     instance void TestingLog.TestClass::.ctor()
IL_0005:  ldc.i4.s   10
IL_0007:  callvirt   instance void TestingLog.TestClass::Test(int32)
IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0011:  pop
IL_0012:  ret
} // end of method Program::Main

.method public hidebysig instance void  Test(int32 logarithmBase) cil managed
{
// Code size       36 (0x24)
.maxstack  3
.locals init ([0] float64 min)
IL_0000:  ldc.r8     0.90000000000000002
IL_0009:  stloc.0
IL_000a:  ldarg.1
IL_000b:  conv.r8
IL_000c:  ldloc.0
IL_000d:  ldarg.1
IL_000e:  conv.r8
IL_000f:  call       float64 [mscorlib]System.Math::Log(float64,
                                                        float64)
IL_0014:  call       float64 [mscorlib]System.Math::Floor(float64)
IL_0019:  call       float64 [mscorlib]System.Math::Pow(float64,
                                                        float64)
IL_001e:  call       void [mscorlib]System.Console::WriteLine(float64)
IL_0023:  ret
} // end of method TestClass::Test

Edit2:从Visual Studio Disassembly窗口中反汇编,断点放在“min”变量定义上。

            double min = 0.9;
00007FFC8A7242D0  sub         rsp,28h  
00007FFC8A7242D4  xorpd       xmm1,xmm1  
            Console.WriteLine(Math.Pow(logarithmBase, Math.Floor(Math.Log(min, logarithmBase))));
00007FFC8A7242D8  movsd       mmword ptr [rsp+20h],xmm1  
00007FFC8A7242DE  xorps       xmm1,xmm1  
00007FFC8A7242E1  cvtsi2sd    xmm1,edx  
00007FFC8A7242E5  movsd       xmm0,mmword ptr [7FFC8A724310h]  
00007FFC8A7242ED  call        00007FFCDA742B40  
00007FFC8A7242F2  call        00007FFCE9E13D90  
00007FFC8A7242F7  movaps      xmm1,xmm0  
00007FFC8A7242FA  movsd       xmm0,mmword ptr [rsp+20h]  
00007FFC8A724300  call        00007FFCE9EA3820  
00007FFC8A724305  call        00007FFCDA6E9E90  
00007FFC8A72430A  nop  
00007FFC8A72430B  add         rsp,28h  
00007FFC8A72430F  ret  

0 个答案:

没有答案