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

.Net内联数学调用在x64版本中产生无穷大,.net,x86,64-bit,.net,X86,64 Bit,我很好奇是否有人可以复制这个问题,或者这只是我的机器的问题。如果我在发布模式下在控制台应用程序中运行以下代码,并且在Project Properties->Build下未选中“Preference 32-bit”选项,它将返回无穷大。但一旦我切换回首选32位,它就会返回0.1 class Program { static void Main(string[] args) { TestClass t = new TestClass(); t.Test

我很好奇是否有人可以复制这个问题,或者这只是我的机器的问题。如果我在发布模式下在控制台应用程序中运行以下代码,并且在Project Properties->Build下未选中“Preference 32-bit”选项,它将返回无穷大。但一旦我切换回首选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))));
    }
}
有趣的是,至少对我来说,如果我将对数基数改为双精度,那么它开始输出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反汇编窗口反汇编,断点位于“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  

在反汇编之后(取消选中“在模块加载时禁用JIT优化”),我当然是指本机反汇编,但也有IL不会有什么坏处,希望这就是您所寻找的。抱歉花了这么长时间。是的,谢谢,它没有显示太多。不幸的是,或者至少我看不出有什么错。在64位的过程中,在线尝试它,得到的答案是0.1。32位浮点运算通常比64位浮点运算精度更高,但对于表达式而言,这不会有任何区别。我看不出如何从10^[Log10(0.9)]中得到无穷大,即使在考虑对数基数变化规则时,使用float也有足够的精度。您可以在另一台机器上尝试它,或者将部分结果存储到vars中吗?