This code appears to throw an exception "Value was either too large or too small for a Decimal."
Somehow changing variables y1, y2, x removes an error. For example, y2 from 41 to 38.
How can I fix this?
Turtle.Speed = 10
x = 10
y1 = 42
y2 = 41
Turtle.Angle = 180
Turtle.MoveTo(x, y2)
Turtle.MoveTo(x, y1)
Error trace:
in System.Decimal..ctor(Double value)
in System.Decimal.op_Explicit(Double value)
in Microsoft.SmallBasic.Library.Primitive.op_Implicit(Double value)
in Microsoft.SmallBasic.Library.Turtle.MoveTo(Primitive x, Primitive y)
in _SmallBasicProgram._Main()
The same in both 1.0 and 1.2 versions.
The problem is the SmallBasic (in version 1.2) Primitive-from-double implementation is flawed. Here is how a double is converted to a Primitive.
new Primitive((Decimal) primitiveDouble);
However, this is an unsafe operation as not all values of a double can be (precisely) represented. In these cases the cast to a Decimal will throw an Exception.
Here is a trivial way to reproduce such an exception in C#:
double x = double.MinValue; // [smallest] denormalized value
decimal f = (decimal)x;
This happens in the MoveTo(x,y)
operation which does trigonometry math to turn the MoveTo
into a Turn
+Move
combination. For some inputs (and where the turtle is), such will result in doubles that cannot be [safely] turned into decimal values.
Using Turn
+Move
explicitly will avoid the problematic math and thus should avoid the problem - at least in this particular case.
For reference, here is the decompiled source of 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
}