module math
module lib/math.mu
import "math"
math provides a collection of mathematical functions.
Imports
Functions
abs#
abs returns the magnitude of n, dropping its sign.
Source lib/math.mu:23
fn abs(n) {
if n < 0 {
return -n
}
return n
}bin#
bin returns the binary literal of value with a 0b prefix.
Source lib/math.mu:186
fn bin(value) {
return _format_with_prefix(value, 2, "0b", false)
}ceil_div#
ceil_div performs ceil division for integers, rounding toward positive infinity.
Source lib/math.mu:115
fn ceil_div(a, b) {
if b == 0 {
return error("ceil_div div by zero")
}
if a % b == 0 {
return a / b
}
if a > 0 && b > 0 {
return a / b + 1
}
if a < 0 && b < 0 {
return a / b + 1
}
return a / b
}clamp#
clamp limits value to the inclusive [low, high] range.
Source lib/math.mu:31
fn clamp(value, low, high) {
if low > high {
return error("clamp range is inverted")
}
if value < low {
return low
}
if value > high {
return high
}
return value
}cos_scaled#
cos_scaled returns cos(degrees) * 2^bits.
Source lib/math.mu:297
fn cos_scaled(degrees, bits) {
pair := sin_cos_scaled(degrees, bits)
if is_error(pair) {
return pair
}
return pair[1]
}div_mod#
div_mod returns quotient and remainder while keeping remainder non-negative, matching the floor mod semantics the time helpers expect.
Source lib/math.mu:148
fn div_mod(value, divisor) {
quotient := value / divisor
remainder := value % divisor
if remainder < 0 {
remainder = remainder + divisor
quotient = quotient - 1
}
return [quotient, remainder]
}format_int#
format_int renders value in the requested base (2-36) bits using optional uppercase digits. format_int(value, base, uppercase?) -> string | ERROR The uppercase flag defaults to false when omitted.
Source lib/math.mu:161
fn format_int(args...) {
// check if len(args) is between 2 and 3
count := len(args)
if count < 2 || count > 3 {
return error("math.format_int expects 2 or 3 arguments")
}
value := args[0]
base := args[1]
if !typing.is_int(base) {
return error("math.format_int base must be an integer")
}
if base < 2 || base > 36 {
return error("math.format_int base must be between 2 and 36")
}
uppercaseFlag := false
if len(args) == 3 {
if !typing.is_bool(args[2]) {
return error("math.format_int uppercase flag must be a boolean")
}
uppercaseFlag = args[2]
}
return _format_signed(value, base, uppercaseFlag)
}gcd#
gcd returns the greatest common divisor of a and b.
Source lib/math.mu:132
fn gcd(a, b) {
if a < 0 {
a = -a
}
if b < 0 {
b = -b
}
while b != 0 {
t := b
b = a % b
a = t
}
return a
}hex#
hex returns the lowercase hexadecimal literal of value with a 0x prefix.
Source lib/math.mu:191
fn hex(value) {
return _format_with_prefix(value, 16, "0x", false)
}is_even#
is_even reports whether n is divisible by 2.
Source lib/math.mu:56
fn is_even(n) {
return n % 2 == 0
}is_odd#
is_odd reports whether n is not divisible by 2.
Source lib/math.mu:61
fn is_odd(n) {
return n % 2 != 0
}max#
max returns the larger of a and b.
Source lib/math.mu:15
fn max(a, b) {
if a > b {
return a
}
return b
}min#
min returns the smaller of a and b.
Source lib/math.mu:7
fn min(a, b) {
if a < b {
return a
}
return b
}normalise_degrees#
normalise_degrees folds an angle into [0, 360).
Source lib/math.mu:306
fn normalise_degrees(degrees) {
h := degrees % 360
if h < 0 {
h = h + 360
}
return h
}num_digits#
num_digits counts decimal digits of n (base 10).
Source lib/math.mu:99
fn num_digits(n) {
if n == 0 {
return 1
}
if n < 0 {
n = -n
}
d := 0
while n > 0 {
n = n / 10
d = d + 1
}
return d
}oct#
oct returns the octal literal of value with a 0o prefix.
Source lib/math.mu:196
fn oct(value) {
return _format_with_prefix(value, 8, "0o", false)
}parse_bin#
parse_bin returns the integer value of the binary literal, supporting optional 0b/0B prefix.
Source lib/math.mu:223
fn parse_bin(text) {
return _parse_int_text(text, 2, "0b", "math.parse_bin")
}parse_hex#
parse_hex returns the integer value of the hexadecimal literal, supporting 0x/0X prefix.
Source lib/math.mu:228
fn parse_hex(text) {
return _parse_int_text(text, 16, "0x", "math.parse_hex")
}parse_int#
parse_int parses text as an integer using the optional base (default 10). parse_int(text, base?) -> int | ERROR
Source lib/math.mu:202
fn parse_int(args...) {
count := len(args)
if count < 1 || count > 2 {
return error("math.parse_int expects 1 or 2 arguments")
}
text := args[0]
base := 10
if count == 2 {
baseArg := args[1]
if !typing.is_int(baseArg) {
return error("math.parse_int base must be an integer")
}
base = baseArg
}
if base < 2 || base > 36 {
return error("math.parse_int base must be between 2 and 36")
}
return _parse_int_text(text, base, nil, "math.parse_int")
}parse_oct#
parse_oct returns the integer value of the octal literal, supporting 0o/0O prefix.
Source lib/math.mu:233
fn parse_oct(text) {
return _parse_int_text(text, 8, "0o", "math.parse_oct")
}pow_10#
pow_10 returns 10^k for non-negative k.
Source lib/math.mu:88
fn pow_10(k) {
n := 1
i := 0
while i < k {
n = n * 10
i = i + 1
}
return n
}sign#
sign returns -1 for negative, 1 for positive, and 0 for zero.
Source lib/math.mu:45
fn sign(n) {
if n < 0 {
return -1
}
if n > 0 {
return 1
}
return 0
}sin_cos_scaled#
sin_cos_scaled returns [sin, cos] of an integer number of degrees, each multiplied by 2^bits. bits may be 0..30; 30 is the precision the computation is carried out at, and anything smaller is shifted down from it.
math.sin_cos_scaled(90, 16) -> [65536, 0]
The four cardinal angles are answered exactly rather than approximated, so a quarter turn is precisely a quarter turn.
Source lib/math.mu:272
fn sin_cos_scaled(degrees, bits) {
if !typing.is_int(degrees) {
return error("math.sin_cos_scaled expects integer degrees, got " + type(degrees))
}
if !typing.is_int(bits) || bits < 0 || bits > _TRIG_BITS {
return error("math.sin_cos_scaled expects bits in 0.." + str(_TRIG_BITS) + ", got " + inspect(bits))
}
pair := _sin_cos_q30(degrees)
if bits == _TRIG_BITS {
return pair
}
shift := _TRIG_BITS - bits
return [pair[0] >> shift, pair[1] >> shift]
}sin_scaled#
sin_scaled returns sin(degrees) * 2^bits.
Source lib/math.mu:288
fn sin_scaled(degrees, bits) {
pair := sin_cos_scaled(degrees, bits)
if is_error(pair) {
return pair
}
return pair[0]
}sqrt#
sqrt returns the square root of n
Source lib/math.mu:66
fn sqrt(n) {
if n < 0 {
return error("Square root of a negative number is undefined.")
}
if n < 2 {
return n
}
// Initial guess: n // 2 or closer approximation
x := n
y := (x + 1) / 2
while y < x {
x = y
y = (x + n / x) / 2
}
return x
}Internal helpers
Underscore-prefixed names are implementation detail. They are listed so the module's source reads without surprises, not as API — they may change at any time.
| _CORDIC_ATAN | atan(2^-i) in degrees * 1,000,000. |
| _CORDIC_K | CORDIC gain compensation in Q30: 0.607252935 * 2^30. |
| _TRIG_BITS | The scale the CORDIC works in: one unit is 2^-30. |
| _TRIG_ONE | — |
| _digit_char(digit_value, uppercase_flag) | digit_char returns the character representing digit_value for the given base. |
| _digit_value(ch) | digit_value returns the numeric value of ch or -1 when invalid. |
| _format_signed(value, base, uppercase_flag) | format_signed renders value in base while keeping the sign. |
| _format_unsigned(value, base, uppercase_flag) | format_unsigned renders the non-negative value in the provided base. |
| _format_with_prefix(value, base, prefix, uppercase_flag) | format_with_prefix renders value and prepends prefix if provided. |
| _matches_prefix_ignore_case(text, prefix, idx) | matches_prefix_ignore_case compares prefix with text starting at idx, ignoring ASCII case. |
| _parse_int_text(text, base, prefix, func_name) | parse_int_text reads a signed integer in the specified base, allowing the optional prefix. |
| _sin_cos_q30(degrees) | _sin_cos_q30 returns [sin, cos] scaled by 2^30. |
| _skip_prefix(text, idx, prefix) | skip_prefix consumes prefix (if present) from text[idx:]. |