.net之不可思议事件(一)
唉,真是惭愧,自己的博客网站一晃就是两个多月没有打理了。这样可不行啊。
今天就来讲个.net的奇异事件,各位高手看了也多多指点。最早是在自己做的一个项目中的,为了方便大家查看,我只抽取了其中关键的代码。
先看以下代码,大家思考一下,执行结果是什么。
float height = 130;
float width = 100;
float scale = height/width;
if(scale<1.3)
{
this.Response.Write("图片长宽比例为 "+ scale +",小于1.3"
;
}
else
{
this.Response.Write("恭喜你,图片符合要求"
;
}
看完后,大家能告诉我执行结果吗?
是
图片长宽比例为 1.3,小于1.3
天啊,为什么会是这个结果???
posted on 2005-02-23 10:47 湘南和也 阅读(1779) 评论(13) 编辑 收藏 引用 收藏至365Key 所属分类: .net技术
评论:
# re: .net之不可思议事件(一) 2005-02-23 12:49 | Jerry Zhou
任何浮点数的运算都有精度损失问题,对于浮点数的比较,不能简单地调用>,==,<,应该求差,看是否在允许的精度范围内。 回复
# re: .net之不可思议事件(一) 2005-02-23 12:49 | BernieJun
是应该这样啊.因为scale被转化为整型与1.3比较.
改为
if((float)scale<1.3)
{
//do some thing
}
回复
# re: .net之不可思议事件(一) 2005-02-23 12:53 | birdshome
浮点数精度问题,使用decimal看看 回复
# re: .net之不可思议事件(一) 2005-02-23 13:01 | caca(卡卡)
(float)scale<1.3也无济于事,因为scale本来就是float的,正是与1.3比较才发生数据类型变化,应该scale<(float)1.3,但是其本质我还不清楚 回复
# re: .net之不可思议事件(一) 2005-02-23 13:02 | BB
改为:
float height = 130;
float width = 100;
float scale = height/width;
if(scale<1.3F)
{
this.Response.Write("图片长宽比例为 "+ scale +",小于1.3"
;
}
else
{
this.Response.Write("恭喜你,图片符合要求"
;
}
回复
# re: .net之不可思议事件(一) 2005-02-23 13:09 | caca(卡卡)
弱弱的问:当scale<1.3进行比较的时候,scale和1.3看成什么数据类型?比较的本质是? 回复
# re: .net之不可思议事件(一) 2005-02-23 13:35 | Bonny.Wong(让思想飞翔)
呵呵,BB和我想的一樣,正是如此。
用float聲明變量時,默認的是double型,加一個F才表示真正的float型。
但是兩個double型進行比較難道就會有差異麼?不明白了。。。 回复
# re: .net之不可思议事件(一) 2005-02-23 14:25 | zhumk
浮点数在计算机中都不是精确保存,所以if(scale<1.3)是不可能得到正确的结果的,我记得这个问题在上学的时候学习计算机时就学过,是这样处理
if (abs(scale-1.3)<0.0000001)
就是说他们相减的绝对值小于某个值
回复
# re: .net之不可思议事件(一) 2005-02-23 15:26 | Icebird
精度问题害死人
为什么不一开始就定义为double类型,这才是正确的做法,一般来说,不要用float,C#如此,Delphi也是如此(不用Single而用Double)
double height = 130;
double width = 100;
double scale = height/width;
if(scale<1.3)
{
this.Response.Write("图片长宽比例为 "+ scale +",小于1.3"
;
}
else
{
this.Response.Write("恭喜你,图片符合要求"
;
} 回复
# re: .net之不可思议事件(一) 2005-02-23 17:08 | 古月春秋
说绝对值问题的都是在瞎掰,尤其是写出“if (abs(scale-1.3)<0.0000001)”的人,这个方法是在判断scale==1.3的时候才用的。是判断相等,不是判断大小的!!
我想要注意的是,scale<1.3 中,scale实际上可能是1.300000000000001,1.3实际上也可能是1.300000000000001,因此最好改一下数据类型 回复
# re: .net之不可思议事件(一) 2005-02-23 19:05 | xingd
.NET中的字面浮点数都被编译器认为是double类型,而scale是float的,float只有7位精度。计算机是二进制存储的,1.3的二进制对应是
1.01001100110011001100110,也就是1.2999999523162841796875,只有7位精度。而double会有15~16位精度,也就是能够保持1.299999999999999xxxx或者是1.300000000000000xxx的值,因此scale < 1.3是成立的。
.NET数值类型精度参见:http://www.cnblogs.com/xingd/archive/2005/01/28/98961.html 回复
# re: .net之不可思议事件(一) 2005-02-24 09:47 | 湘南和也
谢谢大家的出谋划策,经过各位朋友的启发,我自己再修改代码测试了一下。
楼上的Icebird、古月春秋、XINGD大大说的很正确,我现在的代码就是按Icebird的意见改的。另外XINGD的对于存储原理的解释让我明白了两个数据类型之间的差异。 回复
# re: .net之不可思议事件(一) 2005-02-24 10:50 | oo复oo
我认为判断是否小于1.3 还是将height/width的结果先省略到1位小数后才比较更合适 回复