高中一年级新教材第三章第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
"溢出哪位高人,请指点一二不胜感激。。

解决方案 »

  1.   

    LZ:你的
    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
      

  2.   

    好像是x在+-0.001之间时y溢出了,把0<x<0.001和-0.001<x<0排除掉,只是这样做之后会出现坏块。PS:
    我没用做过图像处理的软件,感觉这个0.0001不太合适。
      

  3.   

    这是数据类型的问题,可以把出错的哪个点错误忽略掉,象这样:
    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
      

  4.   

    问个问题:Lz的if语句后的then跑哪里去玩了?
      

  5.   

    原因是x和y超出了Picture控件的坐标允许范围。大概的解决办法如下:
    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                                            '结束程序
      

  6.   


    感谢大家,非常感谢!
    我深深感受到网络的力量是如此的巨大,皆源自于网络人的“热心”。我自己也找出了原因和些许方法,不敢独享,写在下面。原因分析:
    不管是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
    再次感谢大家的热心支持。