Math

The math library adds methods directly to numeric types -- int, long, double, and complex. You call math operations on the values themselves rather than passing them to some static function.

Method-Based Design

Instead of the traditional static function call, I went with methods on values:

// Traditional style (also supported)
public int x;
formula a_x = Math.abs(x);

// Method style (preferred)
formula b_x = x.abs();

The method style is more concise and chains better. Both work, but I prefer the method form.

Maybe Type Support

A lot of math functions also work on maybe<T> types. This matters because some operations -- division being the obvious one -- can produce undefined results. Operating on maybe types lets you chain computations without constantly checking for errors:

maybe<double> result = 10 / 0;  // Empty (division by zero)
maybe<double> valid = 10 / 2;   // Contains 5.0

Type: int

Methods on 32-bit integer values.

abs()

Returns the absolute value.

int x = -42;
int absX = x.abs();  // 42

int y = 17;
int absY = y.abs();  // 17
Parameter Type Description
(none) - -

Returns: int - The absolute value


Type: long

Methods on 64-bit integer values.

abs()

Returns the absolute value.

long x = -9223372036854775807L;
long absX = x.abs();  // 9223372036854775807L
Parameter Type Description
(none) - -

Returns: long - The absolute value


Type: double and maybe

Methods on 64-bit floating point values.

abs()

Returns the absolute value.

double x = -3.14159;
double absX = x.abs();  // 3.14159
Parameter Type Description
(none) - -

Returns: double - The absolute value


sqrt()

Returns the square root. Since the square root of a negative number is complex, this returns a complex type -- which I think is the right call rather than silently returning NaN.

double x = 16.0;
complex sqrtX = x.sqrt();  // @c(4.0, 0.0)

double negative = -4.0;
complex sqrtNeg = negative.sqrt();  // @c(0.0, 2.0)
Parameter Type Description
(none) - -

Returns: complex - The square root (real or complex)


ceil()

Rounds up to the smallest integer greater than or equal to the number.

double x = 3.2;
double ceilX = x.ceil();  // 4.0

double y = -3.7;
double ceilY = y.ceil();  // -3.0
Parameter Type Description
(none) - -

Returns: double - The ceiling value

With precision:

double x = 3.14159;
double ceilX = x.ceil(0.1);  // 3.2
Parameter Type Description
precision double The precision to round to

Returns: double - The ceiling value at the given precision


floor()

Rounds down to the largest integer less than or equal to the number.

double x = 3.7;
double floorX = x.floor();  // 3.0

double y = -3.2;
double floorY = y.floor();  // -4.0
Parameter Type Description
(none) - -

Returns: double - The floor value

With precision:

double x = 3.14159;
double floorX = x.floor(0.1);  // 3.1
Parameter Type Description
precision double The precision to round to

Returns: double - The floor value at the given precision


round()

Rounds to the nearest integer.

double x = 3.4;
double roundX = x.round();  // 3.0

double y = 3.6;
double roundY = y.round();  // 4.0
Parameter Type Description
(none) - -

Returns: double - The rounded value

With precision:

double x = 3.14159;
double roundX = x.round(0.01);  // 3.14
Parameter Type Description
precision double The precision to round to

Returns: double - The rounded value at the given precision


roundTo(digits)

Rounds to a specific number of decimal places. Slightly different flavor than round(precision) -- you specify the digit count instead of the precision value.

double pi = 3.14159265359;
double pi2 = pi.roundTo(2);  // 3.14
double pi4 = pi.roundTo(4);  // 3.1416
Parameter Type Description
digits int Number of decimal places

Returns: double - The rounded value


Trigonometric Functions

These live on the Math class as static functions.

Math.sin(x)

Returns the sine of a value in radians.

maybe<double> result = Math.sin(3.14159 / 2);  // ~1.0
Parameter Type Description
x double The angle in radians

Returns: double - The sine of the angle


Math.cos(x)

Returns the cosine of a value in radians.

double result = Math.cos(0.0);  // 1.0
Parameter Type Description
x double The angle in radians

Returns: double - The cosine of the angle


Math.tan(x)

Returns the tangent of a value in radians.

maybe<double> result = Math.tan(3.14159 / 4);  // ~1.0
Parameter Type Description
x double The angle in radians

Returns: double - The tangent of the angle


Math.PI()

Returns pi. You know, 3.14159...

double pi = Math.PI();  // 3.141592653589793

Returns: double - The value of Pi


Math.sign(x)

Returns the sign of a number: -1, 0, or 1.

int s1 = Math.sign(42);     // 1
int s2 = Math.sign(-42);    // -1
int s3 = Math.sign(0);      // 0
double s4 = Math.sign(3.14);  // 1.0
Parameter Type Description
x int, long, double, or maybe variants The value to check

Returns: Same type as input - The sign of the value


Math.min(a, b)

Returns the smaller of two values.

int smaller = Math.min(10, 20);  // 10
double smaller2 = Math.min(3.14, 2.71);  // 2.71
Parameter Type Description
a int, long, or double First value
b int, long, or double Second value

Returns: Same type as input - The smaller value


Math.intOf(x)

Converts a double to an integer, truncating toward zero.

maybe<int> i = Math.intOf(3.7);  // 3
Parameter Type Description
x double The value to convert

Returns: maybe<int> - The integer value


Math.gcd(a, b)

Returns the greatest common divisor of two integers.

int gcd1 = Math.gcd(20, 50);  // 10
int gcd2 = Math.gcd(10, 13);  // 1
Parameter Type Description
a int First integer
b int Second integer

Returns: int - The greatest common divisor


Type: complex and maybe

Methods on complex number values. I added complex numbers because square roots of negative numbers shouldn't be an error -- they should just be complex.

conj()

Returns the complex conjugate . The conjugate of a + bi is a - bi.

complex z = 3.0 + 4.0 * @i;  // 3 + 4i
complex conjZ = z.conj();     // 3 - 4i
Parameter Type Description
(none) - -

Returns: complex - The complex conjugate


length()

Returns the magnitude of the complex number -- sqrt(a^2 + b^2) per the Pythagorean theorem.

complex z = 3.0 + 4.0 * @i;
double len = z.length();  // 5.0  (3-4-5 triangle)
Parameter Type Description
(none) - -

Returns: double - The magnitude of the complex number


re()

Returns the real part.

complex z = 3.0 + 4.0 * @i;  // 3 + 4i
double real = z.re();         // 3.0
Parameter Type Description
(none) - -

Returns: double - The real component


im()

Returns the imaginary part.

complex z = 3.0 + 4.0 * @i;  // 3 + 4i
double imag = z.im();         // 4.0
Parameter Type Description
(none) - -

Returns: double - The imaginary component


Random Number Generation

Adama has built-in random number generation through the Random class. The random state is part of the document state, so it's deterministic during replay.

Random.genBoundInt(max)

Generates a random integer in the range [0, max).

int roll = Random.genBoundInt(6);  // 0 to 5
Parameter Type Description
max int The exclusive upper bound

Returns: int - A random integer in [0, max)


Random.genInt()

Generates a random 32-bit integer. Useful for shuffling.

int randomValue = Random.genInt();

Returns: int - A random integer

Here's a common pattern -- shuffling a table by assigning random ordering values:

record Card {
  public int id;
  public int ordering;
}

table<Card> deck;

procedure shuffle() {
  (iterate deck).ordering = Random.genInt();
}

Method Summary Tables

Integer Types

Type Method Description Returns
int abs() Absolute value int
long abs() Absolute value long

Floating Point

Type Method Description Returns
double abs() Absolute value double
double sqrt() Square root complex
double ceil() Ceiling double
double ceil(precision) Ceiling at precision double
double floor() Floor double
double floor(precision) Floor at precision double
double round() Round to nearest integer double
double round(precision) Round at precision double
double roundTo(digits) Round to decimal places double

Complex Numbers

Type Method Description Returns
complex conj() Complex conjugate complex
complex length() Magnitude double
complex re() Real part double
complex im() Imaginary part double

Trigonometric and Utility Functions

Function Description Returns
Math.sin(x) Sine of angle (radians) double
Math.cos(x) Cosine of angle (radians) double
Math.tan(x) Tangent of angle (radians) double
Math.PI() Mathematical constant Pi double
Math.sign(x) Sign of number (-1, 0, 1) same as input
Math.min(a, b) Smaller of two values same as input
Math.intOf(x) Convert double to int maybe<int>
Math.gcd(a, b) Greatest common divisor int

Random Generation

Function Description Returns
Random.genBoundInt(max) Generate random int in [0, max) int
Random.genInt() Generate random integer int

Division Safety

It is worth noting that division in Adama always returns maybe<T>. This handles division by zero at the type level rather than crashing at runtime:

procedure foo() {
  int a = 10;
  int b = 0;
  maybe<double> result = a / b;  // Empty (division by zero)

  if (result as value) {
    // Safe to use value here
  }
}

This applies to both integer and floating-point division.

Previous Strings
Next Datetime