两个double变量一个值是1.4一个是1.0结果为什么是0.399....1,而不是0.4呢?(100分)

  • 主题发起人 主题发起人 flash101
  • 开始时间 开始时间
F

flash101

Unregistered / Unconfirmed
GUEST, unregistred user!
两个double变量一个值是1.4一个是1.0结果为什么是0.399....1,而不是0.4呢?
 
精度问题,DOUBLE类型是64位的
所以在定义数据类型的时候要注意
 
用Decimal 吧
 
这个在哪门语言里都存在的,用Decimal可以解决!
转一个讨论帖子,虽然是VB的,对于精度问题依然适用:
=============================================
昨天在VB中碰到两个问题,其实以前就碰到并解决过:
(1)
dim ss asdo
uble
ss = 194268.02 – 194268
肉眼可以判断结果为0.02,而VB中计算的结果:ss = 0.199999999895226E-02
ss = 1.2 - 1 VB计算的结果为:0.2
(2)
dim ss asdo
uble
ss = 400*1000
在VB6中,报越界!!
ss = 400*100000没有异常
分析原因:1:内部二进制与10进制的转换导致Double运算精度问题
2:Int16* Int16VB6以为应该返回Int16,但结果>32767导致越界错误,因此ss=2+32766也会导致溢出,经证实确实如此
这算不算BUG呢?我认为是.
.NET中是否还存在类似问题呢?
经测试在.NET中问题2表面看来已经不存在,但是:
do
uble ss;
int firstInt = 2147483646;
int secondInt = 2;
ss = firstInt + secondInt;
Console.WriteLine(ss);
结果:ss = -2147483648
CLR用int32作为缓冲区,但如果我们的运算结果超出该缓冲区的大小,一样会越界!!
.NET中问题(1)依然如故
这两个问题通过类型转换可以轻松解决,我疑惑的是:从OOP的观点看待该问题,是程序员应该掌握规避方法,还是改变其内部处理机制?你如何看呢?

2004年12月7日 9:49
反馈
# re: 数据类型的BUG还是??? 2004-12-7 10:00 tinyfool
第一个是运算精度问题,vb给的答案没有错误,浮点数本来就是不是精确的,
ss = 0.199999999895226E-02

ss=0.2 可以认为都是正确的。
第二个问题是你自己的错误
ss = 400*1000 当然会溢出
正确写法是
ss = 400.0*1000.0
或者
ss = 400# * 1000#
basic是弱类型语言会自动进行转换没错,但是转换的方式有规律可循的,你也总结了是因为超过了Int16。所以问题在于你用错误的方式去执行这个运算。
ss = 400*100000 不出现问题也相当正常100000这个常量显然超越了Int16的范围。
# re: 数据类型的BUG还是??? 2004-12-7 10:25 大坏蛋
to:tinyfool
事实上,这些值并是不可预期的,事实上我也是使用转换类型的方法解决该问题,但涉及到一个责任划分和分工的问题,我觉得,这种问题不应该是VB程序员职责所在.
"ss = 400*1000 当然会溢出"为何是"当然"?起码.NET中不会溢出,这是内部处理机制的问题
想起我以前的一个项目,有程序员包装了一个Grid控件,只有鼠标在上面转几个圈,程序就异常退出,原因后来查明,是程序捕获鼠标事件,导致溢出,我们是否应该让用户记住这一点,使用时避免移动鼠标呢?还是修改我们的程序?
OOP很重要的一点就是责任划分,我是这样看待这个问题的

# re: 数据类型的BUG还是??? 2004-12-7 10:37 Ninputer
这里存在字面常量的问题。像400,1000,在VB6种是Int16型字面常量,而在C#/VB.NET中是Int32型字面常量。所以在后者中就不会溢出了。
其实是C#/VB.NET中问题产生的条件更难了,并不是就不存在了。正如你后面的例子一样。字面常量的类型是应当指定的,这在VB6,C#或VB.NET中都有完美的语法支持。
至于第一个问题……二进制浮点数无法准确表示0.02,0.02在二进制浮点数中是个循环小数。

# re: 数据类型的BUG还是??? 2004-12-7 10:50 tinyfool
事实上是可以预期的。
我很遗憾你得到了这样的结论。
第一个:我想大部分的编程入门手册都会告诉我们浮点数的精度问题,以及浮点数不能精确表示所有实数的问题,这个是很基础的东西。为什么不应该直接比较两个浮点运算结果等等,这些都是很基础的知识。你用其他语言的浮点运算,也会得到类似的结果
int main()
{
double ss;
ss = 194268.02 - 194268;
return 0;
}
这样的程序你在vc里面跟踪一下,结果是类似的。
第二个:我已经说了,弱类型语言是会自动转换,但是有规律。你的做法违反了规律当然会发生错误。任何语言都有自己的规定(包括一些隐含的),你违反了规定,当然会出现错误。
这里你的实验也可以稍微揭示一下这个转换的规律。
另外,如果需要处理的异常,不去处理,出现问题那当然是程序员的责任。
-----------------------------
我希望你把你的好奇心和精力放在更有意思的地方。比如第一个问题,如果你好好去看看关于浮点数存储的方式,或者自己用比较底层的方式实现一个浮点数加减法,你就会明白,为什么在浮点运算里面194268.02 – 194268居然不完全等于1.2 - 1(实际上,一般是用两个运算结果的差值是都小于一个足够小的数,来判断相等与否的)。这个实验做了以后,你会对浮点数有更深刻的认识。
第二个问题,你可以通过一系列的类似试验得知,vb的自动转换规则。虽然你刚才在抱怨这个转换规则达不到你的要求,但是实际上,转换规则是在效率,已经最大程度减少二义性的前提下的一个折中的结果。正像很多技术都是折中的结果一样。
# re: 数据类型的BUG还是??? 2004-12-7 10:53 tinyfool
眼误,我看成了你说不可预期,我同意这些是可以预期的。
而且这些大部分都是手册可以找到的规则,实际上印象中msdn是包括了对vb怎么对数值进行自动转换的顺序和规律的文档的。
# re: 数据类型的BUG还是??? 2004-12-7 10:58 virushuo
浮点数的问题和编译器相关度很高。可以说是比较复杂的。但是,作为一个程序员,如果你都不了解你的编译器,不了解你的操作系统,那么你还做什么开发呢?只负责画界面?
# re: 数据类型的BUG还是??? 2004-12-7 11:00 大坏蛋
感谢tinyfool和Niputer!
# re: 数据类型的BUG还是??? 2004-12-7 14:22 rIPPER
哈哈,两位又来发镖啦。 ;)
关于这个什么数啊数的,不如用python好了,新版2.4刚刚实现长整数和普通整数的自动转换,保证不会像vb挖个陷阱让你跳。
# re: 数据类型的BUG还是??? 2004-12-7 16:21 DLU
BASIC的数据类型后缀还是很有趣的,我至今习惯把$符号当作字符串。
# re: 数据类型的BUG还是??? 2004-12-7 16:23 DLU
以前的MS BASIC还要注意MS浮点和IEEE浮点之间的区别,似乎也会遭成运算误差来的,忘了,是怎么回事来着?
# re: 数据类型的BUG还是??? 2004-12-7 16:26 Ninputer
VB已经很厉害了,这样的语句都能写
Dim x Asdo
uble = "3" * 4
MsgBox(x)
# re: 数据类型的BUG还是??? 2004-12-7 17:14 xxx
用VB搞东西的对底层还是不熟啊.至少理解方式,思维方式不一致.
这些东西如果让搞汇编的来看,肯定觉得是天经地义的事情吧
# re: 数据类型的BUG还是??? 2004-12-7 18:42 Ocean
是呀,我学过汇编,确实觉得是天经地义
# re: 数据类型的BUG还是??? 2004-12-7 21:37 学生一族
哦.对于第一个问题.如果你想得到0的答案.可以这么做
CDEC(DOUBLE1)-CDEC(DOUBLE2) 就可以了.
这样会自动纠正浮点错误的.
# re: 数据类型的BUG还是??? 2004-12-7 21:38 学生一族
哦.还是我.
没有仔细看.不过 CDEC 是纠正浮点错误.你的答案是 0.02 呵呵.抱歉
# re: 数据类型的BUG还是??? 2004-12-7 22:51 深秋的黎明
dim ss asdo
uble
ss = 194268.02 – 194268
小弟也遇到过这个问题,不过按照小弟的经验
ss.ToString()
的值又会是0.02
不知何解
# re: 数据类型的BUG还是??? 2005-1-10 13:30 我X,一帮傻B
嘿嘿,从某种观点上来看,就是工具不合适,反而怪用的人不好.
手档车自然操作起来容易,但是开自动档的有愿意研究手档怎么开的吗?

# re:数据类型的BUG还是??? 2005-4-10 20:22 牛津杯
^_^,Pretty Good!
# re:数据类型的BUG还是??? 2005-4-16 7:28 拉伸仪
^_^,Pretty Good!
# re:数据类型的BUG还是??? 2005-6-16 22:10 气味检测仪
数据类型的BUG还是???ooeess
# re:数据类型的BUG还是??? 2005-6-16 22:10 一氧化碳测定仪
数据类型的BUG还是???ooeess
# re:数据类型的BUG还是??? 2005-7-16 15:54 红外热像仪
数据类型的BUG还是???ooeess
# re:数据类型的BUG还是??? 2005-8-1 18:00 红外热像仪
数据类型的BUG还是???ooeess
# re: 数据类型的BUG还是??? 2005-11-11 15:30 路过
dim ss asdo
uble
ss = 194268.02 – 194268
肉眼可以判断结果为0.02,而VB中计算的结果:ss = 0.199999999895226E-02
(这里应该是打错了) 应该是:1.99999999895226E-02
 
多人接受答案了。
 

Similar threads

回复
0
查看
863
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
后退
顶部