forked from nulang-org/nulang
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmath.nula
More file actions
119 lines (101 loc) · 2.8 KB
/
Copy pathmath.nula
File metadata and controls
119 lines (101 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Nulang standard library — math functions.
// Language version: 2.0.0-alpha
/// Absolute value.
pub fn abs(x: Int) -> Int {
if x < 0 then -x else x
}
/// Minimum of two integers.
pub fn min(a: Int, b: Int) -> Int {
if a < b then a else b
}
/// Maximum of two integers.
pub fn max(a: Int, b: Int) -> Int {
if a > b then a else b
}
/// Clamp x to the range [lo, hi].
pub fn clamp(x: Int, lo: Int, hi: Int) -> Int {
if x < lo then lo
else if x > hi then hi
else x
}
/// Sign: -1 for negative, 0 for zero, 1 for positive.
pub fn sign(x: Int) -> Int {
if x > 0 then 1
else if x < 0 then -1
else 0
}
/// Integer exponentiation (base^exp) for non-negative exp.
pub fn pow(base: Int, exp: Int) -> Int {
let rec loop = fn(b: Int, e: Int, acc: Int) -> Int {
if e == 0 then acc
else loop(b, e - 1, acc * b)
};
loop(base, exp, 1)
}
/// Factorial. Returns 1 for n <= 1.
pub fn factorial(n: Int) -> Int {
let rec loop = fn(i: Int, acc: Int) -> Int {
if i <= 1 then acc
else loop(i - 1, acc * i)
};
loop(n, 1)
}
/// Greatest common divisor (Euclidean algorithm).
pub fn gcd(a: Int, b: Int) -> Int {
if b == 0 then abs(a)
else gcd(b, a % b)
}
/// Least common multiple.
pub fn lcm(a: Int, b: Int) -> Int {
let d = gcd(a, b);
if d == 0 then 0 else abs(a * b) / d
}
/// True when n is even.
pub fn is_even(n: Int) -> Bool {
n % 2 == 0
}
/// True when n is odd.
pub fn is_odd(n: Int) -> Bool {
n % 2 != 0
}
/// Square root via Newton's method. Returns -1.0 for negative input.
pub fn sqrt(x: Float) -> Float {
if x < 0.0 then -1.0
else if x == 0.0 then 0.0
else {
var guess = x / 2.0;
var i = 0;
while i < 20 {
guess = (guess + x / guess) / 2.0;
i = i + 1
};
guess
}
}
// ── Rounding ──────────────────────────────────────────────────────────────
/// Round to nearest integer, 0.5 rounds away from zero.
pub fn round(x: Float) -> Float {
if x >= 0.0 then perform Int.to_float(perform Float.to_int(x + 0.5))
else perform Int.to_float(perform Float.to_int(x - 0.5))
}
/// Largest integer ≤ x.
pub fn floor(x: Float) -> Int {
let t = perform Float.to_int(x);
if x < 0.0 && perform Int.to_float(t) != x then t - 1
else t
}
/// Smallest integer ≥ x.
pub fn ceil(x: Float) -> Int {
let t = perform Float.to_int(x);
if perform Int.to_float(t) == x then t
else if x >= 0.0 then t + 1
else t
}
/// Truncate toward zero.
pub fn trunc(x: Float) -> Int {
perform Float.to_int(x)
}
/// True when x has no fractional part.
pub fn is_int(x: Float) -> Bool {
perform Int.to_float(perform Float.to_int(x)) == x
}