问题是 SmallBasic(1.2 版)Primitive-from-double 实现存在缺陷。下面是如何将 double 转换为 Primitive。
new Primitive((Decimal) primitiveDouble);
然而,这是一个不安全的操作,因为并非所有的双精度值都可以(精确)表示。在这些情况下,转换为 Decimal 将引发异常。
这是在 C# 中重现此类异常的一种简单方法:
double x = double.MinValue; // [smallest] denormalized value
decimal f = (decimal)x;
这发生在MoveTo(x,y)
执行三角数学以将MoveTo
转换为Turn
+Move
组合的操作中。对于某些输入(以及海龟所在的位置),这将导致无法 [安全地] 转换为十进制值的双精度数。
显式使用Turn
+将避免有问题的数学,因此应该避免问题 - 至少在这种特殊情况下。Move
作为参考,这里是MoveTo的反编译源:
/// <summary>
/// Turns and moves the turtle to the specified location. If the pen is down, it will draw a line as it moves.
/// </summary>
/// <param name="x">The x co-ordinate of the destination point.</param>
/// <param name="y">The y co-ordinate of the destination point.</param>
public static void MoveTo(Primitive x, Primitive y)
{
double d = (double) ((x - Turtle.X) * (x - Turtle.X) + (y - Turtle.Y) * (y - Turtle.Y));
if (d == 0.0)
return;
double num1 = System.Math.Sqrt(d);
double num2 = System.Math.Acos((double) (Turtle.Y - y) / num1) * 180.0 / System.Math.PI;
if ((bool) (x < Turtle.X))
num2 = 360.0 - num2;
double num3 = num2 - (double) ((int) Turtle.Angle % 360);
if (num3 > 180.0)
num3 -= 360.0;
Turtle.Turn((Primitive) num3); // goes boom here..
Turtle.Move((Primitive) num1); // ..or here
}