这是我电脑上发生的情况
(double)(float)0.6 = 0.60000002384185791 (double)0.6f = 0.60000002384185791 (double)(6/10f) = 0.6 (double)(float)(6/10f) = 0.6
6 / 10f也是一个浮点数,怎么可以精确到0.6?
在我心里(双)(6 / 10f)也应该是0.60000002384185791.
有人可以帮忙解释一下吗谢谢!
解决方法
首先,重要的是要记住,0.6不能被准确地表示为一个浮点数,但是它可以被准确地表示为一个双重的(浮点算术的不准确性是有据可查的,如果不清楚为什么0.6不能被准确地表示为一个浮点数,尝试
this link)
您看到上述行为的原因在于编译器 – 如果您在反射器中查看编译的程序集,那么这里的内容有点清楚:
(更新我已经改变了代码,以便它不使用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;
为什么编译器选择以这种特定的方式编译是超出我的(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;
编译器似乎在几个特殊情况下做了上述的伎俩,为什么只有当转换为双精度时才完全超出我的范围!
其余的时间似乎做了一些诡计,使浮点算术似乎工作,其实通常不会.