commit - ea03bfa556eeaf3f10a455e6b5f529257bee028b
commit + afccd2672f33f8db43d1d7290f7c0c25daaecef2
blob - 09f75a4eebbfe103cfd27d9f4b491e10830143f8
blob + 5267d993e8cabdd120bb33ff40697062085caf05
--- include/lfmath.h
+++ include/lfmath.h
int binstr_to_int(const char *s);
+int abs_int(int i);
+
int is_power_of_two(int i);
+int gcd(int a, int b);
+
+int lcm(int a, int b);
+
+float lerp(float a, float b, float t);
+
+int isqrt(int n);
+
Point *bresenham(int x0, int y0, int x1, int y1, size_t *sz);
Point *bresenham_p(Point p1, Point p2, size_t *sz);
blob - 5659ee6ca791e2ed0df101b495a7236946c2a812
blob + 08fed2d2db0c250cc94df7548df5cff989f536f2
--- src/math.c
+++ src/math.c
return bresenham(p1.x, p1.y, p2.x, p2.y, sz);
}
+int abs_int(int i) {
+ return i < 0 ? -i : i;
+}
+
int is_power_of_two(int i) {
return i > 0 && (i & (i - 1)) == 0;
}
+
+int gcd(int a, int b) {
+ a = abs_int(a);
+ b = abs_int(b);
+ while (b) {
+ int tmp = b;
+ b = a % b;
+ a = tmp;
+ }
+ return a;
+}
+
+int lcm(int a, int b) {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+ return abs_int(a / gcd(a, b) * b);
+}
+
+float lerp(float a, float b, float t) {
+ return a + t * (b - a);
+}
+
+int isqrt(int n) {
+ if (n < 0) {
+ return -1;
+ }
+ if (n < 2) {
+ return n;
+ }
+ int x = n;
+ int y = (x + 1) / 2;
+ while (y < x) {
+ x = y;
+ y = (x + n / x) / 2;
+ }
+ return x;
+}
blob - 780eca704baf4f47eec03ef622bf50095d48d0bb
blob + 50629b4a980d0cab64d560728ae38875b324dfb6
--- tests/test_math.c
+++ tests/test_math.c
i = clamp_int(i, 2, 5);
ASSERT_EQ(i, 5);
+ /* abs_int */
+ ASSERT_EQ(abs_int(5), 5);
+ ASSERT_EQ(abs_int(-5), 5);
+ ASSERT_EQ(abs_int(0), 0);
+
+ /* gcd */
+ ASSERT_EQ(gcd(12, 8), 4);
+ ASSERT_EQ(gcd(7, 13), 1);
+ ASSERT_EQ(gcd(0, 5), 5);
+ ASSERT_EQ(gcd(5, 0), 5);
+ ASSERT_EQ(gcd(-12, 8), 4);
+ ASSERT_EQ(gcd(-6, -9), 3);
+
+ /* lcm */
+ ASSERT_EQ(lcm(4, 6), 12);
+ ASSERT_EQ(lcm(7, 13), 91);
+ ASSERT_EQ(lcm(1, 5), 5);
+ ASSERT_EQ(lcm(0, 5), 0);
+
+ /* lerp */
+ ASSERT_TRUE(lerp(0.0f, 10.0f, 0.0f) == 0.0f);
+ ASSERT_TRUE(lerp(0.0f, 10.0f, 1.0f) == 10.0f);
+ ASSERT_TRUE(lerp(0.0f, 10.0f, 0.5f) == 5.0f);
+ ASSERT_TRUE(lerp(2.0f, 4.0f, 0.25f) == 2.5f);
+
+ /* isqrt */
+ ASSERT_EQ(isqrt(0), 0);
+ ASSERT_EQ(isqrt(1), 1);
+ ASSERT_EQ(isqrt(25), 5);
+ ASSERT_EQ(isqrt(26), 5);
+ ASSERT_EQ(isqrt(100), 10);
+ ASSERT_EQ(isqrt(-1), -1);
+
size_t sz = 0;
Point *line = bresenham(0, 0, 2, 5, &sz);
ASSERT_TRUE(sz > 0);