该练习的目标是编写一个求解一元二次方程的VSL脚本。给定表达式ax^2+bx+c = 0及a,b,c的值,求x。
算法如下:
delta = b^2-4ac 如果 delta < 0 那么 无解 否则 就有一个或两个解: x' = (-b+sqrt(delta))/2a x'' = (-b-sqrt(delta))/2a
- 新建一个Virtools作品,创建一个脚本,并像之前的两个练习一样创建一个 名为“Run VSL” 的BB到脚本中。将这个BB重命名为"Solve 2nd Degree"(不包括引号),切换到 VSL Script Manager,添加3个浮点(float)类型的pIn参数,分别命名为:a、b、c;及2个个浮点(float)类型的pOut参数,分别命名为x1、x2。
- 输入以下代码到代码窗口中:
void main()
{
if (!a)
return;
float delta = pow(b, 2)-4*a*c;
if (delta >= 0)
{
x1 = (-b+sqrt(delta))/2*a;
x2 = (-b-sqrt(delta))/2*a;
}
} - 编译这个VSL脚本,切换到Schematic 工作区中,给以下3个pIn参数赋值:
- a = 3
- b = 5
- c = -3
- 运行你的VSL脚本,检查pOut;你应该会看到以下结果:x1 = 4.21537 x2 = -19.2154。
虽然这个VSL脚本功能是正确的,但还可以进行优化。当前的delta的开方运算被执行了两次。然而可以让它只运算一次,只要先存储这个值,在后面的脚本中重新使用它就可以了。 - 修改你的VSL脚本为:
void main()
{
if (!a)
return;
float delta = pow(b, 2)-4*a*c;
if (delta >= 0)
{
float sqrtDelta = sqrt(delta);
x1 = (-b+sqrtDelta)/2*a;
x2 = (-b-sqrtDelta)/2*a;
}
} - 再次编译VSL脚本,并运行它。
你很可能发现没有什么不同。这是正常的,因为这个VSL脚步太小了。然而,就是像这样的很多细小优化可以大大减少作品的整个执行时间(这当然是件好事情)。
这个脚本可以更进一步的优化,如果x的值不需要计算的话:
- 当‘a’等于0时,这个脚本可以停止,因为这种情况已经不是一元二次方程了。
- 假如delta是负数时,这个脚本可以停止,因为无解。
- 在VSL Script Manager右边,右击bOut并选择Add bOut。重复此操作,再加入一个bOut。然后将这两个bOut重命名为“Not Second Degree”和“No Solution”。
请注意VSL Script Manager会将这两个bOut重命名为:"Not_Second_Degree" 和"No_Solution" - VSL不支持带空格的变量名。同时也注意到bOut的类型是布尔(TRUE为on,FALSE为off)。并且这个类型不能改变。 - 修改代码如下:
void main()
{
if (!a)
{
Not_Second_Degree = TRUE;
return;
}
float delta = pow(b, 2)-4*a*c;
if (delta >= 0)
{
float sqrtDelta = sqrt(delta);
x1 = (-b+sqrtDelta)/2*a;
x2 = (-b-sqrtDelta)/2*a;
}
else
{
No_Solution = TRUE;
return;
}
Out = TRUE;
} - 现在,你的脚本有了三个可以被激活的bOut,根据输入的数据在必要的时候做出响应。
注意:当VSL脚本只有一个bOut的时候,不需要显式激活该bOut,当VSL脚本执行完代码以后它被自动处理。
然而,当有两个或更多的bOut时,你就必须书写脚本,以便在恰当的时候显式地激活恰当的bOut。