高中一年级新教材第三章第2节,有个VB编程问题(画y=x^2的图象),其原始代码是这样的:
Private Sub Command1_Click() '确定按钮单击事件
Dim x, y As Single '定义x,y两个变量
Picture1.Scale (-10, 25)-(10, -25) '定义坐标系
Picture1.Line (-10, 0)-(10, 0), RGB(0, 0, 255) '画横坐标轴,颜色为蓝色
Picture1.Line (0, 25)-(0, -25), RGB(0, 0, 255) '画纵坐标轴,颜色为蓝色
'用循环语句描点画函数图像
For x = -10 To 10 Step 0.0001 'x值从-10变化到10,每次增量为0.0001
y = x ^ 2 '根据表达式y=x2来计算y值
Picture1.PSet (x, y), RGB(255, 0, 0) '根据x,y的值用红色描点
Next x '取下一个增量后的x值
End Sub '结束程序有个同学 想改画 y=x+1/x的图象,作为老师,我非常高兴,结果,就出了问题,因为,在-10~10之间有个0,而0不能作分母,于是,把上面的for……next之间的程序如下:
For x = -10 To 10 Step 0.0001
if x <> 0 '当x为0时,不执行就跳过去了
y = x + 1/x
Picture1.PSet (x, y), RGB(255, 0, 0)
end if
Next x
可偏偏问题还是出了,说
"实时错误:6
"溢出哪位高人,请指点一二不胜感激。。
Private Sub Command1_Click() '确定按钮单击事件
Dim x, y As Single '定义x,y两个变量
Picture1.Scale (-10, 25)-(10, -25) '定义坐标系
Picture1.Line (-10, 0)-(10, 0), RGB(0, 0, 255) '画横坐标轴,颜色为蓝色
Picture1.Line (0, 25)-(0, -25), RGB(0, 0, 255) '画纵坐标轴,颜色为蓝色
'用循环语句描点画函数图像
For x = -10 To 10 Step 0.0001 'x值从-10变化到10,每次增量为0.0001
y = x ^ 2 '根据表达式y=x2来计算y值
Picture1.PSet (x, y), RGB(255, 0, 0) '根据x,y的值用红色描点
Next x '取下一个增量后的x值
End Sub '结束程序有个同学 想改画 y=x+1/x的图象,作为老师,我非常高兴,结果,就出了问题,因为,在-10~10之间有个0,而0不能作分母,于是,把上面的for……next之间的程序如下:
For x = -10 To 10 Step 0.0001
if x <> 0 '当x为0时,不执行就跳过去了
y = x + 1/x
Picture1.PSet (x, y), RGB(255, 0, 0)
end if
Next x
可偏偏问题还是出了,说
"实时错误:6
"溢出哪位高人,请指点一二不胜感激。。
Dim x, y As Single句有问题(这里实际将x定义为变体类型)
应该为
Dim x As Single, y As Single
Private Sub Command1_Click()
Dim x As Single, y As Single '定义x,y两个变量
Picture1.Scale (-10, 25)-(10, -25) '定义坐标系
Picture1.Line (-10, 0)-(10, 0), RGB(0, 0, 255) '画横坐标轴,颜色为蓝色
Picture1.Line (0, 25)-(0, -25), RGB(0, 0, 255) '画纵坐标轴,颜色为蓝色
'用循环语句描点画函数图像
For x = -10 To 10 Step 0.0001 'x值从-10变化到10,每次增量为0.0001
If x <> 0 Then ' '当x为0时,不执行就跳过去了
y = x + 1 / x
Picture1.PSet (x, y), RGB(255, 0, 0)
End If
Next x
End Sub
我没用做过图像处理的软件,感觉这个0.0001不太合适。
Option ExplicitPrivate Sub Command1_Click() '确定按钮单击事件
Dim x, y As Single '定义x,y两个变量
Picture1.Scale (-10, 25)-(10, -25) '定义坐标系
Picture1.Line (-10, 0)-(10, 0), RGB(0, 0, 255) '画横坐标轴,颜色为蓝色
Picture1.Line (0, 25)-(0, -25), RGB(0, 0, 255) '画纵坐标轴,颜色为蓝色
'用循环语句描点画函数图像
On Error Resume Next
For x = -10 To 10 Step 0.0001
If x <> 0 Then '当x为0时,不执行就跳过去了
y = x + 1 / x
Picture1.PSet (x, y), RGB(255, 0, 0)
End If
Next xEnd Sub
Private Sub Command2_Click() '确定按钮单击事件
Dim x, y As Single '定义x,y两个变量
Picture1.Scale (-10, 25)-(10, -25) '定义坐标系
Picture1.Line (-10, 0)-(10, 0), RGB(0, 0, 255) '画横坐标轴,颜色为蓝色
Picture1.Line (0, 25)-(0, -25), RGB(0, 0, 255) '画纵坐标轴,颜色为蓝色
'用循环语句描点画函数图像
For x = -10 To 10 Step 0.0001
If x <> 0 Then '当x为0时,不执行就跳过去了
y = x + 1 / x
cX = Abs(x) <= Abs(Picture1.ScaleWidth) '粗略地检测是否超出范围
cY = Abs(y) <= Abs(Picture1.ScaleHeight) '粗略地检测是否超出范围
If cX And cY Then
Picture1.PSet (x, y), RGB(255, 0, 0)
End If
End If
Next x
End Sub '结束程序
感谢大家,非常感谢!
我深深感受到网络的力量是如此的巨大,皆源自于网络人的“热心”。我自己也找出了原因和些许方法,不敢独享,写在下面。原因分析:
不管是single,还是double,都叫浮点数,有效范围非常大,但在运算时,有可能产生进位误差。因此,在-10~10范围中取x值,再加上一个步长值0.0001,每次结果不一定完全正确,有可能产生误差,比如:
-10
-9.9999
-9.9998
……
-4.9999
-4.999799999999999(or -4.999800000000001)
-4.999699999999999(or -4.999700000000001) ……
本来,从-10开始,每次递进0.0001,一定能保证“有一个时刻x可以取到0”,但经上面变化(一旦产生误差)后,就很难有机会再回到“x能取到0的状态”,因此,我所提问题的代码中:
if x <> 0
y = x + 1/x
Picture1.PSet (x, y), RGB(255, 0, 0)
end if
就永远也不会有x=0的可能了,会一直执行下去,有可能跳过0,就一切OK了;也有可能跳不过0,会出现一个非常小的数(即非常接近于0的数,姑且把该数叫做“临界数”),再被1除时,会超出单(或双)精度范围,这样一来,就会出现“实时错误:6 溢出”。
解决问题的方法:方法有三,但宗旨是一样的,即跳过“0”值,以保证“1/x”永远有效。分别如下:1.处理“临界数”法
For x = -10 To 10 Step 0.0001
If Abs(x) <> 0.0001 And x < 0 Then x = x + 0.0001 y = x + 1 / x '当出现一个非常小的值(又是负数,且若再加步长值0.0001,则变正数)时,可让其直接再加步长值,可跳过"0",以保证能正确运行下去。
Picture1.PSet (x, y), RGB(255, 0, 0)
Next x
2.四舍五入法
For x = -10 To 10 Step 0.0001
x = Round(x, 4) '4即保证了与步长的小数点后位数一致,因为进位误差非常小,通过四舍五入,就可以消除误差,从而能保证总一个机会,可以让x取到“0”值,也可跳过“0”值
If x <> 0 Then
y = x + 1 / x '当x=0时,不会执行到这句
Picture1.PSet (x, y), RGB(255, 0, 0)
end if
Next x
3.错误忽略法
就是5楼(阿根迁巫师)的方法,也写在下方。
On Error Resume Next '当出现错误时,忽略错误,条数不限,可轻松跳过x的“0”值。
For x = -10 To 10 Step 0.0001
y = x + 1 / x
Picture1.PSet (x, y), RGB(255, 0, 0)
Next x
再次感谢大家的热心支持。