代码加咖啡的生活

专门讨论.NET相关技术--大坏蛋
随笔 - 29, 评论 - 253, 引用 - 67

导航

关于


标签

每月存档

最新留言

广告

 

昨天在VB中碰到两个问题,其实以前就碰到并解决过:

(1)

dim ss as double

ss = 194268.02 – 194268

肉眼可以判断结果为0.02,而VB中计算的结果:ss = 0.199999999895226E-02

ss = 1.2 - 1 VB计算的结果为:0.2

(2)

dim ss as double

ss = 400*1000

在VB6中,报越界!!

ss = 400*100000没有异常

分析原因:1:内部二进制与10进制的转换导致Double运算精度问题

 2:Int16* Int16VB6以为应该返回Int16,但结果>32767导致越界错误,因此ss=2+32766也会导致溢出,经证实确实如此

这算不算BUG呢?我认为是.

.NET中是否还存在类似问题呢?

经测试在.NET中问题2表面看来已经不存在,但是:

 double ss;
 int firstInt = 2147483646;
 int secondInt = 2;
 ss = firstInt + secondInt;
 Console.WriteLine(ss);

结果:ss = -2147483648

CLR用int32作为缓冲区,但如果我们的运算结果超出该缓冲区的大小,一样会越界!!

.NET中问题(1)依然如故

这两个问题通过类型转换可以轻松解决,我疑惑的是:从OOP的观点看待该问题,是程序员应该掌握规避方法,还是改变其内部处理机制?你如何看呢?

 

打印 | 张贴于 2004-12-07 09:49:00 | Tag:暂无标签

留言反馈

#回复: 请问缓冲区中数据类型 编辑
public dataid as string,dataid_l%,dataid_R%
dataid="x90x10"
dataid_l = Asc(Mid(dataid, 1, 1))
dataid_r = Asc(Mid(dataid, 2, 1))
MsgBox "正在接收..." & Right(Hex(dataid_l), 2) & Right(Hex(dataid_r), 2), vbOKOnly, "接收"



为什么显示出来的是正在接收...7839

恳求各位大侠指点。
2007-06-27 18:16:00 | [匿名:dorimi]
#re: 数据类型的BUG还是??? 编辑
dim ss as double

ss = 194268.02 – 194268

肉眼可以判断结果为0.02,而VB中计算的结果:ss = 0.199999999895226E-02
(这里应该是打错了) 应该是:1.99999999895226E-02
2005-11-11 15:30:00 | [匿名:路过]
#re:数据类型的BUG还是??? 编辑
数据类型的BUG还是???ooeess
2005-06-16 22:10:00 | [匿名:气味检测仪]
#re:数据类型的BUG还是??? 编辑
数据类型的BUG还是???ooeess
2005-06-16 22:10:00 | [匿名:一氧化碳测定仪]
#re:数据类型的BUG还是??? 编辑
^_^,Pretty Good!
2005-04-16 07:28:00 | [匿名:拉伸仪]
#re:数据类型的BUG还是??? 编辑
^_^,Pretty Good!
2005-04-10 20:22:00 | [匿名:牛津杯]
#re: 数据类型的BUG还是??? 编辑
嘿嘿,从某种观点上来看,就是工具不合适,反而怪用的人不好.
手档车自然操作起来容易,但是开自动档的有愿意研究手档怎么开的吗?
2005-01-10 13:30:00 | [匿名:我X,一帮傻B]
#re: 数据类型的BUG还是??? 编辑
dim ss as double

ss = 194268.02 – 194268

小弟也遇到过这个问题,不过按照小弟的经验

ss.ToString()

的值又会是0.02

不知何解
2004-12-07 22:51:00 | [匿名:深秋的黎明]
#re: 数据类型的BUG还是??? 编辑
哦.还是我.

没有仔细看.不过 CDEC 是纠正浮点错误.你的答案是 0.02 呵呵.抱歉
2004-12-07 21:38:00 | [匿名:学生一族]
#re: 数据类型的BUG还是??? 编辑
哦.对于第一个问题.如果你想得到0的答案.可以这么做

CDEC(DOUBLE1)-CDEC(DOUBLE2) 就可以了.

这样会自动纠正浮点错误的.
2004-12-07 21:37:00 | [匿名:学生一族]
#re: 数据类型的BUG还是??? 编辑
是呀,我学过汇编,确实觉得是天经地义
2004-12-07 18:42:00 | [匿名:Ocean]
#re: 数据类型的BUG还是??? 编辑
用VB搞东西的对底层还是不熟啊.至少理解方式,思维方式不一致.
这些东西如果让搞汇编的来看,肯定觉得是天经地义的事情吧
2004-12-07 17:14:00 | [匿名:xxx]
#re: 数据类型的BUG还是??? 编辑
VB已经很厉害了,这样的语句都能写
Dim x As Double = "3" * 4
MsgBox(x)
2004-12-07 16:26:00 | [匿名:Ninputer]
#re: 数据类型的BUG还是??? 编辑
以前的MS BASIC还要注意MS浮点和IEEE浮点之间的区别,似乎也会遭成运算误差来的,忘了,是怎么回事来着?
2004-12-07 16:23:00 | [匿名:DLU]
#re: 数据类型的BUG还是??? 编辑
BASIC的数据类型后缀还是很有趣的,我至今习惯把$符号当作字符串。
2004-12-07 16:21:00 | [匿名:DLU]
#re: 数据类型的BUG还是??? 编辑
哈哈,两位又来发镖啦。 ;)

关于这个什么数啊数的,不如用python好了,新版2.4刚刚实现长整数和普通整数的自动转换,保证不会像vb挖个陷阱让你跳。
2004-12-07 14:22:00 | [匿名:rIPPER]
#re: 数据类型的BUG还是??? 编辑
感谢tinyfool和Niputer!
2004-12-07 11:00:00 | [匿名:大坏蛋]
#re: 数据类型的BUG还是??? 编辑
浮点数的问题和编译器相关度很高。可以说是比较复杂的。但是,作为一个程序员,如果你都不了解你的编译器,不了解你的操作系统,那么你还做什么开发呢?只负责画界面?
2004-12-07 10:58:00 | [匿名:virushuo]
#re: 数据类型的BUG还是??? 编辑
眼误,我看成了你说不可预期,我同意这些是可以预期的。
而且这些大部分都是手册可以找到的规则,实际上印象中msdn是包括了对vb怎么对数值进行自动转换的顺序和规律的文档的。
2004-12-07 10:53:00 | [匿名:tinyfool]
#re: 数据类型的BUG还是??? 编辑
事实上是可以预期的。
我很遗憾你得到了这样的结论。

第一个:我想大部分的编程入门手册都会告诉我们浮点数的精度问题,以及浮点数不能精确表示所有实数的问题,这个是很基础的东西。为什么不应该直接比较两个浮点运算结果等等,这些都是很基础的知识。你用其他语言的浮点运算,也会得到类似的结果
int main()
{
double ss;
ss = 194268.02 - 194268;
return 0;
}
这样的程序你在vc里面跟踪一下,结果是类似的。

第二个:我已经说了,弱类型语言是会自动转换,但是有规律。你的做法违反了规律当然会发生错误。任何语言都有自己的规定(包括一些隐含的),你违反了规定,当然会出现错误。
这里你的实验也可以稍微揭示一下这个转换的规律。

另外,如果需要处理的异常,不去处理,出现问题那当然是程序员的责任。
-----------------------------
我希望你把你的好奇心和精力放在更有意思的地方。比如第一个问题,如果你好好去看看关于浮点数存储的方式,或者自己用比较底层的方式实现一个浮点数加减法,你就会明白,为什么在浮点运算里面194268.02 – 194268居然不完全等于1.2 - 1(实际上,一般是用两个运算结果的差值是都小于一个足够小的数,来判断相等与否的)。这个实验做了以后,你会对浮点数有更深刻的认识。

第二个问题,你可以通过一系列的类似试验得知,vb的自动转换规则。虽然你刚才在抱怨这个转换规则达不到你的要求,但是实际上,转换规则是在效率,已经最大程度减少二义性的前提下的一个折中的结果。正像很多技术都是折中的结果一样。
2004-12-07 10:50:00 | [匿名:tinyfool]
#re: 数据类型的BUG还是??? 编辑
这里存在字面常量的问题。像400,1000,在VB6种是Int16型字面常量,而在C#/VB.NET中是Int32型字面常量。所以在后者中就不会溢出了。
其实是C#/VB.NET中问题产生的条件更难了,并不是就不存在了。正如你后面的例子一样。字面常量的类型是应当指定的,这在VB6,C#或VB.NET中都有完美的语法支持。
至于第一个问题……二进制浮点数无法准确表示0.02,0.02在二进制浮点数中是个循环小数。
2004-12-07 10:37:00 | [匿名:Ninputer]
#re: 数据类型的BUG还是??? 编辑
to:tinyfool
事实上,这些值并是不可预期的,事实上我也是使用转换类型的方法解决该问题,但涉及到一个责任划分和分工的问题,我觉得,这种问题不应该是VB程序员职责所在.
"ss = 400*1000 当然会溢出"为何是"当然"?起码.NET中不会溢出,这是内部处理机制的问题
想起我以前的一个项目,有程序员包装了一个Grid控件,只有鼠标在上面转几个圈,程序就异常退出,原因后来查明,是程序捕获鼠标事件,导致溢出,我们是否应该让用户记住这一点,使用时避免移动鼠标呢?还是修改我们的程序?
OOP很重要的一点就是责任划分,我是这样看待这个问题的
2004-12-07 10:25:00 | [匿名:大坏蛋]
#re: 数据类型的BUG还是??? 编辑
第一个是运算精度问题,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的范围。
2004-12-07 10:00:00 | [匿名:tinyfool]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.2.0