From 6fb84a85a35d723b02d54f68d11d38541bab91b7 Mon Sep 17 00:00:00 2001 From: cassowarii <2374677+cassowarii@users.noreply.github.com> Date: Thu, 9 Jul 2026 23:25:25 -0700 Subject: [PATCH] project euler #3 --- sample/project_euler/pe03.sa | 26 ++++++++++++++++++++++++++ src/data/integer.c | 18 ++++++++++++++---- src/data/integer.h | 6 ++++-- src/lib/module/math.c | 4 ++-- 4 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 sample/project_euler/pe03.sa diff --git a/sample/project_euler/pe03.sa b/sample/project_euler/pe03.sa new file mode 100644 index 0000000..2c4c002 --- /dev/null +++ b/sample/project_euler/pe03.sa @@ -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 } diff --git a/src/data/integer.c b/src/data/integer.c index 4426bf1..5d75198 100644 --- a/src/data/integer.c +++ b/src/data/integer.c @@ -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; } } diff --git a/src/data/integer.h b/src/data/integer.h index 48f5af5..84c4075 100644 --- a/src/data/integer.h +++ b/src/data/integer.h @@ -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); diff --git a/src/lib/module/math.c b/src/lib/module/math.c index f9d690d..c04e32c 100644 --- a/src/lib/module/math.c +++ b/src/lib/module/math.c @@ -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 @@ -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 { -- 1.8.3.1