project euler #3
authorcassowarii <2374677+cassowarii@users.noreply.github.com>
Fri, 10 Jul 2026 06:25:25 +0000 (23:25 -0700)
committercassowarii <2374677+cassowarii@users.noreply.github.com>
Fri, 10 Jul 2026 06:25:25 +0000 (23:25 -0700)
sample/project_euler/pe03.sa [new file with mode: 0644]
src/data/integer.c
src/data/integer.h
src/lib/module/math.c

diff --git a/sample/project_euler/pe03.sa b/sample/project_euler/pe03.sa
new file mode 100644 (file)
index 0000000..2c4c002
--- /dev/null
@@ -0,0 +1,26 @@
+def max_positive list {
+  let result = 0
+
+  list.each => element {
+    result = element if element > result
+  }
+
+  result
+}
+
+def factors num {
+  let list = []
+  let candidate = 2
+  let max = math::sqrt num
+  while candidate <= max {
+    list.push candidate if num %% candidate
+    candidate = candidate + 1
+  }
+  list
+}
+
+def prime? num {
+  factors(num).length == 0
+}
+
+println max_positive factors(600851475143).filter => num { prime? num }
index 4426bf1..5d75198 100644 (file)
@@ -103,9 +103,7 @@ hInteger sbInteger_sum(hInteger a, hInteger b) {
 
     trim_bigint(result);
 
-    hInteger ret = finalize_bigint(a, b, result);
-
-    return ret;
+    return finalize_bigint(a, b, result);
   }
 }
 
@@ -128,7 +126,19 @@ double sbInteger_as_double(hInteger a) {
   if (!is_bigint(a)) {
     return (double)a;
   } else {
-    PANIC("agh! i haven't done this!");
+    bigint *big = find_bigint_for_handle(a);
+    i8 sgn = int_sign(big, a);
+    isize size = int_size(big);
+    double result = 0.0;
+    for (isize i = size - 1; i >= 0; i--) {
+      /* this definitely loses precision. i wonder if there is a better way to do this */
+      result *= BIGINT_PIECE_MAX;
+      result += int_piece(big, a, i);
+    }
+
+    if (sgn < 0) result *= -1;
+
+    return result;
   }
 }
 
index 48f5af5..84c4075 100644 (file)
@@ -2,8 +2,8 @@
 
 #include "data/value.h"
 
-#define SARABANDE_INT_MAX ((1LL << 31) - 1)
-#define SARABANDE_INT_MIN (-(1LL << 31) + 1)
+#define SARABANDE_INT_MAX ((1LL << 48) - 1)
+#define SARABANDE_INT_MIN (-(1LL << 48) + 1)
 
 void sbInteger_sys_init();
 
@@ -23,4 +23,6 @@ void sbInteger_fprint(FILE *out, hInteger a);
 
 usize sbInteger_snprint(char *buf, usize size, hInteger a);
 
+double sbInteger_as_double(hInteger a);
+
 void sbInteger_method(hVm vm);
index f9d690d..c04e32c 100644 (file)
@@ -4,6 +4,7 @@
 #include "data/list.h"
 #include "data/string.h"
 #include "data/symbol.h"
+#include "data/integer.h"
 #include "vm/exec.h"
 
 #include <math.h>
@@ -18,8 +19,7 @@ static void sbsqrt(hVm vm, usize argc) {
 
   double original_value;
   if (argument->type == IT_INTEGER) {
-    original_value = (double)argument->integer;
-    printf("%g\n", original_value);
+    original_value = sbInteger_as_double(argument->integer);
   } else if (argument->type == IT_FLOAT) {
     original_value = argument->float_val;
   } else {