思维的乐趣

Enjoy it
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.NET/C# 中float double相关的两个小知识点

Posted on 2010-02-17 22:19  szh114  阅读(3241)  评论(5编辑  收藏  举报

  今天在一个C#练习100例中看到这么一段代码:

 

1 float f_a = 2323.03f;
2 double d_a = 2323.03d;
3 bool b_a = (f_a == d_a);
4 Console.WriteLine(b_a);

说是输出结果是 FALSE,我还不信,结果一试没想还真是。。。。。有点无语,为什么呢?这一点也太容易让人犯错了吧。

 

  例子中的注释里写道:”这里的结果是False,同是2323.03,因为数据类型不同,存储的长度也不同,其近似结果也不同,故不相等。“

  存储长度不能拿来说事吧,总不成两头补了一堆0,就认为是数据值不同?这跟C#的自然风格好像不太符合呀,这儿应该是相等才合理嘛,在内部进行一个

将短类型转换成长类型再比较的隐式操作不行么?

  那好,我手动强制进行转换再看看,

 

1 float f_a = 2323.03f;
2 double d_a = 2323.03d;
3 bool b_a = ((double)f_a == d_a);
4 Console.WriteLine(b_a);

结果仍然是FALSE,那我就真不明白了,强制转换了,还不相等,那就只能把这个FLOAT赋值给一个DOUBLE型变量再来比喽?真麻烦,搞不懂

 

  我忽然想到,那我把DOUBLE强制转换成FLOAT再比比看:

 

1 float f_a = 2323.03f;
2 double d_a = 2323.03d;
3 bool b_a = (f_a == (float)d_a);
4 Console.WriteLine(b_a);

真是崩溃。。。。。这次竟然输出TRUE,相等了。。。。。。。。

 

  那我再试试INT 跟FLOAT ,DOUBLE之间比怎么个情况:

 

代码
1 int i_a = 23;
2 float f_a = 23f;
3 double d_a = 23d;
4 bool b_a = (i_a == f_a);
5 Console.WriteLine(b_a);
6 b_a = (i_a == d_a);
7 Console.WriteLine(b_a);

 

这次好了,两个TRUE,,,,,,,

 

  要么就干脆秉承强类型的风格,不同类型的不能比,要允许比了,就智能一点,这搞得。。。

  以后要记住,不同类型的数值,不能乱比。即使强制类型转换了也不好使!

 

 

后记: 浮点数在内存中的表示形式及浮点数比较

浮点数的表示和基本运算

深入浅出浮点数

 

 

再后记:

前几天在代码中碰到了这个的一个问题,关于两个float型相减的问题,大概就是如下:

 

  float f1 = 935.5f;
  float f2 = 909.9f;

 

然后对 f1,f2 做了一个减法,结果并不是正确的 25.6 ,而是 25.59998。有了前面的教训,我就想到多半又是浮点数的内部存储格式的原因。

也就是说,这个25.9998是怎么来的,我得弄清楚,然后,我再找到解决的办法。

 

如果说这是所谓的浮点型在计算机中二进制无法精确表示的原因,那么在其它语言中它也应该是会有错误的,然后我就下了个DEV C++ 跑了如下的程序:

 

    float f1 = 935.5f;
    float f2 = 909.9f;
   
    cout<<f3<<endl;

 

显示输出结果是 25.6, 人家这儿是对的。。。。那是怎么回事呢。。。。。。

然后网上一通乱查,看到这么一句:“浮点计算都有精度问题。每个编译器都有调整精度的编译选项的。如果把精度调高,应该就不会出现这种问题。
但是速度也会相应变慢。” 我就去VS2008里面找看有没有这个设置项。结果是没找到。。。。。

 

还有人这么说:“你说的这个问题在所有编译器中都存在,甚至所有语言都存在,Double就是这个样子的,如果要精确运算,就不要用浮点数,将小数拆成两个整型再计算。后来出现的很多语言提供了专门存放货币的精确小数类型。”

 

可是所谓的将小数拆成两个整形再计算,这是怎么个拆法来着???????不懂。。。。。

 

to be continued...