c# – 为什么是(双)0.6f>(双)(6 / 10f)?

前端之家收集整理的这篇文章主要介绍了c# – 为什么是(双)0.6f>(双)(6 / 10f)?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我电脑上发生的情况
  1. (double)(float)0.6
  2. = 0.60000002384185791
  3.  
  4. (double)0.6f
  5. = 0.60000002384185791
  6.  
  7. (double)(6/10f)
  8. = 0.6
  9.  
  10. (double)(float)(6/10f)
  11. = 0.6

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

解决方法

首先,重要的是要记住,0.6不能被准确地表示为一个浮点数,但是它可以被准确地表示为一个双重的(浮点算术的不准确性是有据可查的,如果不清楚为什么0.6不能被准确地表示为一个浮点数,尝试 this link)

您看到上述行为的原因在于编译器 – 如果您在反射器中查看编译的程序集,那么这里的内容有点清楚:

(更新我已经改变了代码,以便它不使用Console.WriteLine,因为我意识到编译器为你选择一个重载,这困惑的情况)

  1. // As written in source
  2. var j = (double)(float)0.6;
  3. var k = (double)0.6f;
  4. var l = (double)(6/10f);
  5. var m = (double)(float)(6/10f);
  6.  
  7. // Code as seen by Reflector
  8. double j = 0.60000002384185791;
  9. double k = 0.60000002384185791;
  10. double l = 0.6;
  11. double m = 0.6;

为什么编译器选择以这种特定的方式编译是超出我的(fyi,这是所有的优化被关闭)

一些有趣的其他情况:

  1. // Code
  2. var a = 0.6;
  3. var b = (double)0.6;
  4. var c = 0.6f;
  5. var d = (float)0.6;
  6.  
  7. var e = 6 / 10;
  8. var f = 6 / (10f);
  9. var g = (float)(6 / 10);
  10. var h = 6 / 10f;
  11. var i = (double)6 / 10;
  12. // Prints out 0.60000002384185791
  13.  
  14. double n = (float)0.6;
  15. double o = f;
  16.  
  17. // As seen by Reflector
  18. double a = 0.6;
  19. double b = 0.6;
  20. float c = 0.6f;
  21. float d = 0.6f;
  22.  
  23. int e = 0;
  24. float f = 0.6f;
  25. float g = 0f;
  26. float h = 0.6f;
  27. double i = 0.6;
  28.  
  29. double n = 0.60000002384185791;
  30. double o = f;

编译器似乎在几个特殊情况下做了上述的伎俩,为什么只有当转换为双精度时才完全超出我的范围!

其余的时间似乎做了一些诡计,使浮点算术似乎工作,其实通常不会.

猜你在找的C#相关文章