为什么(双)0.6f>(双)(6/10f)?

zhy*_*002 10 c#

这是我的电脑上发生的事情:

(double)(float)0.6
= 0.60000002384185791

(double)0.6f
= 0.60000002384185791

(double)(6/10f)
= 0.6

(double)(float)(6/10f)
= 0.6
Run Code Online (Sandbox Code Playgroud)

6/10f也是浮子,怎么可以精确到0.6?
在我看来(双)(6/10f)也应该是0.60000002384185791.有人可以帮忙解释一下吗?谢谢!

Jus*_*tin 5

首先,重要的是要记住,0.6不能准确地表示为a float然而它可以准确地表示为double(浮点运算的不准确性有很好的记录,如果不清楚为什么0.6不能准确表示为浮点数,请尝试此链接)

您之所以看到上述行为,原因在于编译器 - 如果您查看反射器中已编译的程序集,那么这里的内容会更清晰一些:

(更新我已经更改了代码以便它不使用Console.WriteLine,因为我意识到编译器正在为您选择一个重载,这使情况混淆)

// As written in source
var j = (double)(float)0.6;
var k = (double)0.6f;
var l = (double)(6/10f);
var m = (double)(float)(6/10f);

// Code as seen by Reflector
double j = 0.60000002384185791;
double k = 0.60000002384185791;
double l = 0.6;
double m = 0.6;
Run Code Online (Sandbox Code Playgroud)

为什么编译器选择以这种特殊的方式编译是超出我的(fyi,这是关闭优化的全部)

其他一些有趣的案例:

// Code
var a = 0.6;
var b = (double)0.6;
var c = 0.6f;
var d = (float)0.6;

var e = 6 / 10;
var f = 6 / (10f);
var g = (float)(6 / 10);
var h = 6 / 10f;
var i = (double)6 / 10;
// Prints out 0.60000002384185791

double n = (float)0.6;
double o = f;

// As seen by Reflector
double a = 0.6;
double b = 0.6;
float c = 0.6f;
float d = 0.6f;

int e = 0;
float f = 0.6f;
float g = 0f;
float h = 0.6f;
double i = 0.6;

double n = 0.60000002384185791;
double o = f;
Run Code Online (Sandbox Code Playgroud)

编译器似乎只在几个特殊情况下执行上述技巧,为什么只有在转换为double时才能完成此操作完全超出我的范围!

其余的时间它似乎做了一些技巧,使浮点运算似乎工作,实际上它通常不会.

  • 0.6无法准确表示为双精度数. (4认同)
  • @Rick是对的,这个答案是对的.3/5在基数2中无限重复,因此它不能完全表示为"double"或*any*有限二进制数. (2认同)