Math
Math provides random-number generation, integer and floating-point arithmetic helpers, transcendental functions, and a full set of mathematical constants. All methods are static.
#import <Math.xt>The class makes heavy use of xtc’s overloading by return type for zero-argument methods — Math.rand() and the constants like Math.PI() resolve based on the variable being assigned to. The compiler emits the version that produces the requested type.
Random numbers
Section titled “Random numbers”xtc’s RNG is a small linear-feedback generator. By default it auto-seeds from the Atari hardware (RANDOM register at $D20A) at first use; you can also seed it explicitly.
static void setSeed(u16 seed); // re-seed the generatorstatic void step(void); // advance the generator one tickUnbounded rand() overloads
Section titled “Unbounded rand() overloads”static u8 rand(void);static u16 rand(void);static u32 rand(void);static float rand(void); // 0.0 ≤ x < 1.0static double rand(void); // 0.0 ≤ x < 1.0u8 b = Math.rand(); // 0..255u16 w = Math.rand(); // 0..65535u32 l = Math.rand(); // 0..2^32-1float f = Math.rand(); // 0.0 ≤ f < 1.0double d = Math.rand(); // 0.0 ≤ d < 1.0Bounded rand overloads
Section titled “Bounded rand overloads”static u8 rand(u8 max); // 0 ≤ x < maxstatic u8 rand(u8 lo, u8 hi); // lo ≤ x ≤ histatic u16 rand(u16 max); // 0 ≤ x < maxstatic u16 rand(u16 lo, u16 hi); // lo ≤ x ≤ hiu8 d6 = Math.rand((u8)1, (u8)6); // dice rollu16 cell = Math.rand((u16)40); // 0..39Absolute value
Section titled “Absolute value”static i8 abs(i8 v);static i16 abs(i16 v);static i32 abs(i32 v);static float abs(float v);static double abs(double v);i32 delta = Math.abs(target - current);Square root
Section titled “Square root”static float sqrt(float v);static double sqrt(double v);float hypot = Math.sqrt(dx * dx + dy * dy);Logarithms and exponentials
Section titled “Logarithms and exponentials”static float ln(float v);static double ln(double v);static float exp(float x);static double exp(double x);ln is natural log (base e); exp is e^x. For other bases, multiply / divide by Math.LN2(), Math.LN10(), etc.
Powers
Section titled “Powers”pow is overloaded by exponent type — for integer exponents the integer-typed overload is much cheaper than the float-by-float version.
static float pow(float base, float power);static float pow(float base, i16 power);static double pow(double base, double power);static double pow(double base, i16 power);static double pow(double base, i32 power);static double pow(double base, u32 power);float r2 = Math.pow(r, (i16)2); // squared, integer fast pathfloat v = Math.pow((float)2.0, (float)0.5); // square root via powTrigonometry
Section titled “Trigonometry”Angles are in radians. All four functions exist in both float and double precision.
static float sin(float angle);static float cos(float angle);static float tan(float angle);static float atan(float x);
static double sin(double angle);static double cos(double angle);static double tan(double angle);static double atan(double x);float a = Math.PI() / 4;float s = Math.sin(a); // ≈ 0.7071float c = Math.cos(a);Constants
Section titled “Constants”Both float and double versions of the standard constants are available; the compiler picks based on the assignment target.
| Method | Value |
|---|---|
Math.E() | Euler’s number |
Math.LOG2E() | log₂(e) |
Math.LOG10E() | log₁₀(e) |
Math.LN2() | ln(2) |
Math.LN10() | ln(10) |
Math.PI() | π |
Math.PI_2() | π / 2 |
Math.PI_4() | π / 4 |
Math.INV_PI() | 1 / π |
Math.TWO_PI() | 2π |
Math.TWO_SQRTPI() | 2 / √π |
Math.SQRT2() | √2 |
Math.SQRT1_2() | √(1/2) |
float pi_f = Math.PI(); // float overloaddouble pi_d = Math.PI(); // double overloadA note on the float format
Section titled “A note on the float format”float in xtc is a 5-byte binary value: 1 sign byte + 1 signed binary exponent byte + 3 bytes of mantissa (24 bits) with an implicit leading 1. The value is (1 + mantissa / 2^24) * 2^exp for normal numbers. double is 8 bytes — same shape, with a 48-bit mantissa for ~15 digits of precision.
This is not the Atari OS math pack format. The Atari ROM uses BCD-encoded floats with a 6-decimal-digit mantissa; xtc uses pure binary, which is much faster to multiply and divide on a CPU that has no decimal arithmetic support, at the cost of needing a binary↔ASCII conversion routine to print. The format is defined by the xtc runtime, not by the host OS, so it’s identical on Atari and on Commodore — only the helper-routine implementations differ per platform.
The hand-written assembler routines in support/generic/asm/float/ and support/generic/asm/double/ implement add, subtract, multiply, divide, and the math functions on this format. Code generated by xtc emits JSR to those routines automatically when float operations appear in source.
Code-size gating
Section titled “Code-size gating”Math.xt uses conditional compilation extensively — every transcendental, the entire double family, the pow overloads, and the constants are gated behind feature flags (ENABLE_DOUBLE, ENABLE_TRIG, etc.) so a program that only needs rand() doesn’t pay the binary cost of sin and cos. The defaults pull in everything; pass -DENABLE_DOUBLE=0, -DENABLE_TRIG=0, etc. to opt out per feature.
Platform notes
Section titled “Platform notes”The Math class also exists under support/commodore/lib/Math.xt for the C64. The API is the same — same overloads, same constants — and because the xtc float and double formats are platform-independent (binary, defined by the language not the host OS), the bit-level layout of values is identical on both platforms. The C64 implementation differs only in its assembly helpers and per-platform tuning.