简体   繁体   English

VS2012和VS2015之间的float / double转换的区别

[英]difference of float/double conversion betwen VS2012 and VS2015

I have the following code: 我有以下代码:

 float a = 0.02f * 28f;
 double b = (double)a;
 double c = (double)(0.02f * 28f);
 Console.WriteLine(String.Format("  {0:F20}",  b));
 Console.WriteLine(String.Format("  {0:F20}", c));

However it returns different results whether it's compiled from VS2012 or VS2015 (both have "standard" settings) 但是,无论是从VS2012还是VS2015编译(均具有“标准”设置),它都会返回不同的结果

In VS2012 在VS2012中

0,56000000238418600000
0,55999998748302500000

In VS2015: 在VS2015中:

0,56000000238418600000
0,56000000238418600000

VS2012 dissasembly: VS2012散布:

           float a = 0.02f * 28f;
0000003a  mov         dword ptr [ebp-40h],3F0F5C29h 
            double b = (double)a;
00000041  fld         dword ptr [ebp-40h] 
00000044  fstp        qword ptr [ebp-48h] 
            double c = (double)(0.02f * 28f);
00000047  fld         qword ptr ds:[001D34D0h] 
0000004d  fstp        qword ptr [ebp-50h] 

VS2015 dissasembly: VS2015散布:

            float a = 0.02f * 28f;
001E2DE2  mov         dword ptr [ebp-40h],3F0F5C29h  
            double b = (double)a;
001E2DE9  fld         dword ptr [ebp-40h]  
001E2DEC  fstp        qword ptr [ebp-48h]  
            double c = (double)(0.02f * 28f);
001E2DEF  fld         dword ptr ds:[1E2E7Ch]  
001E2DF5  fstp        qword ptr [ebp-50h]  

As we can see the disassembly is not identical in both cases, is this normal? 如我们所见,两种情况下的拆卸都不相同,这是否正常? Could this be a bug in VS2012 or VS2015 ? 这可能是VS2012或VS2015中的错误吗? Or is this behaviour controlled by some specific setting that was changed? 还是这种行为受更改的某些特定设置控制? thanks! 谢谢!

The issue here is that in the Roslyn compiler, constant floating point calculations done at compile time are performed slightly differently from earlier versions - which is resulting in different behaviour. 这里的问题是在Roslyn编译器中,在编译时执行的恒定浮点计算与早期版本的执行略有不同-这导致了不同的行为。

However, this is not a bug because of this section of the C# standard: 但是,由于C#标准的这一部分,这不是错误:

4.1.6 Floating-point types 4.1.6浮点类型

Floating-point operations may be performed with higher precision than the result type of the operation. 浮点运算可以比运算的结果类型更高的精度执行。 For example, some hardware architectures support an “extended” or “long double” floating-point type with greater range and precision than the double type, and implicitly perform all floating-point operations using this higher precision type. 例如,某些硬件体系结构支持比双精度类型具有更大范围和精度的“扩展”或“长双精度”浮点类型,并使用此更高精度类型隐式执行所有浮点运算。 Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. 只有付出过高的性能代价,才能使此类硬件体系结构以较低的精度执行浮点运算,而不是要求实现同时牺牲性能和精度,而C#允许将高精度类型用于所有浮点运算。 。 Other than delivering more precise results, this rarely has any measurable effects. 除了提供更精确的结果外,这几乎没有任何可测量的效果。 However, in expressions of the form x * y / z, where the multiplication produces a result that is outside the double range, but the subsequent division brings the temporary result back into the double range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity. 但是,在形式为x * y / z的表达式中,乘法运算得出的结果超出了double范围,但是随后的除法将临时结果带回double范围,因此该表达式的计算结果较高。范围格式可能会导致产生有限的结果,而不是无穷大。 To force a value of a floating point type to the exact precision of its type, an explicit cast can be used. 为了强制将浮点类型的值精确到其类型的精度,可以使用显式强制转换。

What's happening is that you are seeing the results of undefined behaviour resulting from the above, where the floating point calculation being done at compile time by the Roslyn compiler is using a different precision from the calculation done at compile time by earlier compilers. 发生的是,您看到的是由上述情况导致的未定义行为的结果,其中Roslyn编译器在编译时执行的浮点计算使用的精度与早期编译器在编译时进行的计算的精度不同。

Note that there was actually a bug in the initial release of the Roslyn compiler which was fixed by Update 2: https://github.com/dotnet/roslyn/issues/7262 - but this is just a point of interest and is not directly related to the differences in results between VS2012 and VS2015 (with Update 2). 请注意,Roslyn编译器的初始版本中实际上存在一个错误,该错误已由更新2修复: https : //github.com/dotnet/roslyn/issues/7262-但这只是一个兴趣点,并非直接存在与VS2012和VS2015(更新2)之间的结果差异有关。

Also see the following for more details: 另请参阅以下内容以获取更多详细信息:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM