redscript-mc 1.2.26 → 1.2.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -9
- package/README.zh.md +61 -4
- package/dist/__tests__/stdlib-advanced.test.js +114 -0
- package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/__tests__/stdlib-bigint.test.js +428 -0
- package/dist/data/arena/function/__load.mcfunction +6 -0
- package/dist/data/arena/function/__tick.mcfunction +2 -0
- package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
- package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
- package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
- package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
- package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
- package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
- package/dist/data/arena/function/arena_tick.mcfunction +11 -0
- package/dist/data/counter/function/__load.mcfunction +5 -0
- package/dist/data/counter/function/__tick.mcfunction +2 -0
- package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
- package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/counter/function/counter_tick.mcfunction +11 -0
- package/dist/data/gcd2/function/__load.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd2/function/abs.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd2/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/__load.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3/function/abs.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3/function/test.mcfunction +7 -0
- package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
- package/dist/data/gcd3nm/function/test.mcfunction +7 -0
- package/dist/data/gcd_test/function/__load.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/abs.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
- package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
- package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
- package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
- package/dist/data/isqrttest/function/__load.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
- package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
- package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
- package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
- package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
- package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
- package/dist/data/isqrttest/function/test.mcfunction +6 -0
- package/dist/data/mathtest/function/__load.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mathtest/function/abs.mcfunction +6 -0
- package/dist/data/mathtest/function/test.mcfunction +5 -0
- package/dist/data/minecraft/tags/function/load.json +5 -0
- package/dist/data/minecraft/tags/function/tick.json +5 -0
- package/dist/data/mypack/function/__load.mcfunction +13 -0
- package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
- package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
- package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/abs.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
- package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
- package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
- package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
- package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
- package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
- package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
- package/dist/data/mypack/function/my_game.mcfunction +10 -0
- package/dist/data/quiz/function/__load.mcfunction +16 -0
- package/dist/data/quiz/function/__tick.mcfunction +6 -0
- package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
- package/dist/data/quiz/function/answer_a.mcfunction +4 -0
- package/dist/data/quiz/function/answer_b.mcfunction +4 -0
- package/dist/data/quiz/function/answer_c.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
- package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
- package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
- package/dist/data/quiz/function/ask_question.mcfunction +7 -0
- package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
- package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
- package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
- package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
- package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
- package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
- package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
- package/dist/data/reqtest/function/__load.mcfunction +4 -0
- package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
- package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
- package/dist/data/reqtest/function/use_table.mcfunction +4 -0
- package/dist/data/reqtest2/function/__load.mcfunction +3 -0
- package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
- package/dist/data/runtime/function/__load.mcfunction +5 -0
- package/dist/data/runtime/function/__tick.mcfunction +2 -0
- package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
- package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
- package/dist/data/shop/function/__load.mcfunction +7 -0
- package/dist/data/shop/function/__tick.mcfunction +3 -0
- package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
- package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
- package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
- package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
- package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
- package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
- package/dist/data/swap_test/function/__load.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
- package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
- package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
- package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
- package/dist/data/turret/function/__load.mcfunction +5 -0
- package/dist/data/turret/function/__tick.mcfunction +4 -0
- package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
- package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
- package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
- package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
- package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
- package/dist/data/turret/function/turret_tick.mcfunction +5 -0
- package/dist/gcd2.map.json +15 -0
- package/dist/gcd3.map.json +17 -0
- package/dist/gcd_test.map.json +15 -0
- package/dist/isqrttest.map.json +15 -0
- package/dist/lowering/index.js +71 -4
- package/dist/mathtest.map.json +6 -0
- package/dist/mypack.map.json +27 -0
- package/dist/pack.mcmeta +6 -0
- package/dist/reqtest.map.json +4 -0
- package/dist/reqtest2.map.json +4 -0
- package/dist/runtime/index.js +26 -5
- package/dist/runtime.map.json +7 -0
- package/dist/swap_test.map.json +14 -0
- package/editors/vscode/package-lock.json +2 -2
- package/editors/vscode/package.json +1 -1
- package/examples/showcase.mcrs +505 -0
- package/package.json +1 -1
- package/src/__tests__/stdlib-advanced.test.ts +120 -0
- package/src/__tests__/stdlib-bigint.test.ts +427 -0
- package/src/lowering/index.ts +75 -4
- package/src/runtime/index.ts +27 -5
- package/src/stdlib/advanced.mcrs +81 -0
- package/src/stdlib/bigint.mcrs +205 -0
- package/src/stdlib/math.mcrs +19 -6
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// bigint.mcrs — Arbitrary precision integer arithmetic for RedScript.
|
|
2
|
+
//
|
|
3
|
+
// Representation:
|
|
4
|
+
// 8 limbs, base B = 10000 (10^4) per limb.
|
|
5
|
+
// Limb[0] = least significant (ones place in base 10000).
|
|
6
|
+
// Maximum value: 10^32 - 1 (32 decimal digits).
|
|
7
|
+
// Stored in NBT int arrays inside data storage ("rs:bigint").
|
|
8
|
+
//
|
|
9
|
+
// Registers: "a", "b", "c" (three independent BigInt values).
|
|
10
|
+
//
|
|
11
|
+
// Usage example:
|
|
12
|
+
// bigint_init();
|
|
13
|
+
// bigint_from_int_a(12345678); // a = 12345678
|
|
14
|
+
// bigint_from_int_b(87654321); // b = 87654321
|
|
15
|
+
// bigint_add(); // c = a + b = 99999999
|
|
16
|
+
// let limb0: int = bigint_get_c(0); // → 9999 (c[0])
|
|
17
|
+
// let limb1: int = bigint_get_c(1); // → 9999 (c[1])
|
|
18
|
+
//
|
|
19
|
+
// Multiply overflow note:
|
|
20
|
+
// bigint_mul uses grade-school O(n^2) algorithm.
|
|
21
|
+
// Per-product max: 9999 * 9999 + 9999 + 9999 = 99,999,999 < INT32 ✓
|
|
22
|
+
|
|
23
|
+
module library;
|
|
24
|
+
|
|
25
|
+
// ── Initialization ────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
// Initialize (or reset) all BigInt registers to zero.
|
|
28
|
+
// Must be called once before using any bigint operation.
|
|
29
|
+
fn bigint_init() {
|
|
30
|
+
storage_set_array("rs:bigint", "a", "[0,0,0,0,0,0,0,0]");
|
|
31
|
+
storage_set_array("rs:bigint", "b", "[0,0,0,0,0,0,0,0]");
|
|
32
|
+
storage_set_array("rs:bigint", "c", "[0,0,0,0,0,0,0,0]");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ── Load from int32 ───────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
// Set register a from a 32-bit integer (splits into up to 3 limbs).
|
|
38
|
+
// Supports any n in [0, 999999999999] (12-digit safe limit).
|
|
39
|
+
fn bigint_from_int_a(n: int) {
|
|
40
|
+
storage_set_array("rs:bigint", "a", "[0,0,0,0,0,0,0,0]");
|
|
41
|
+
storage_set_int("rs:bigint", "a", 0, n % 10000);
|
|
42
|
+
storage_set_int("rs:bigint", "a", 1, n / 10000 % 10000);
|
|
43
|
+
storage_set_int("rs:bigint", "a", 2, n / 10000 / 10000);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Set register b from a 32-bit integer.
|
|
47
|
+
fn bigint_from_int_b(n: int) {
|
|
48
|
+
storage_set_array("rs:bigint", "b", "[0,0,0,0,0,0,0,0]");
|
|
49
|
+
storage_set_int("rs:bigint", "b", 0, n % 10000);
|
|
50
|
+
storage_set_int("rs:bigint", "b", 1, n / 10000 % 10000);
|
|
51
|
+
storage_set_int("rs:bigint", "b", 2, n / 10000 / 10000);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ── Read limb ─────────────────────────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
fn bigint_get_a(i: int) -> int { return storage_get_int("rs:bigint", "a", i); }
|
|
57
|
+
fn bigint_get_b(i: int) -> int { return storage_get_int("rs:bigint", "b", i); }
|
|
58
|
+
fn bigint_get_c(i: int) -> int { return storage_get_int("rs:bigint", "c", i); }
|
|
59
|
+
|
|
60
|
+
// ── Copy between registers ────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
fn bigint_copy_a_to_b() {
|
|
63
|
+
let i: int = 0;
|
|
64
|
+
while (i < 8) {
|
|
65
|
+
storage_set_int("rs:bigint", "b", i, storage_get_int("rs:bigint", "a", i));
|
|
66
|
+
i = i + 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fn bigint_copy_b_to_a() {
|
|
71
|
+
let i: int = 0;
|
|
72
|
+
while (i < 8) {
|
|
73
|
+
storage_set_int("rs:bigint", "a", i, storage_get_int("rs:bigint", "b", i));
|
|
74
|
+
i = i + 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn bigint_copy_c_to_a() {
|
|
79
|
+
let i: int = 0;
|
|
80
|
+
while (i < 8) {
|
|
81
|
+
storage_set_int("rs:bigint", "a", i, storage_get_int("rs:bigint", "c", i));
|
|
82
|
+
i = i + 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fn bigint_copy_c_to_b() {
|
|
87
|
+
let i: int = 0;
|
|
88
|
+
while (i < 8) {
|
|
89
|
+
storage_set_int("rs:bigint", "b", i, storage_get_int("rs:bigint", "c", i));
|
|
90
|
+
i = i + 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── Addition: c = a + b ───────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
// c = a + b (carry propagated across all 8 limbs)
|
|
97
|
+
fn bigint_add() {
|
|
98
|
+
let carry: int = 0;
|
|
99
|
+
let i: int = 0;
|
|
100
|
+
while (i < 8) {
|
|
101
|
+
let s: int = storage_get_int("rs:bigint", "a", i)
|
|
102
|
+
+ storage_get_int("rs:bigint", "b", i)
|
|
103
|
+
+ carry;
|
|
104
|
+
carry = s / 10000;
|
|
105
|
+
storage_set_int("rs:bigint", "c", i, s % 10000);
|
|
106
|
+
i = i + 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ── Subtraction: c = a - b (assumes a ≥ b) ──────────────────────────────────
|
|
111
|
+
|
|
112
|
+
fn bigint_sub() {
|
|
113
|
+
let borrow: int = 0;
|
|
114
|
+
let i: int = 0;
|
|
115
|
+
while (i < 8) {
|
|
116
|
+
let d: int = storage_get_int("rs:bigint", "a", i)
|
|
117
|
+
- storage_get_int("rs:bigint", "b", i)
|
|
118
|
+
- borrow;
|
|
119
|
+
if (d < 0) {
|
|
120
|
+
d = d + 10000;
|
|
121
|
+
borrow = 1;
|
|
122
|
+
} else {
|
|
123
|
+
borrow = 0;
|
|
124
|
+
}
|
|
125
|
+
storage_set_int("rs:bigint", "c", i, d);
|
|
126
|
+
i = i + 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ── Comparison: returns 1 (a>b), 0 (a==b), -1 (a<b) ─────────────────────────
|
|
131
|
+
|
|
132
|
+
fn bigint_compare() -> int {
|
|
133
|
+
let i: int = 7;
|
|
134
|
+
while (i >= 0) {
|
|
135
|
+
let ai: int = storage_get_int("rs:bigint", "a", i);
|
|
136
|
+
let bi: int = storage_get_int("rs:bigint", "b", i);
|
|
137
|
+
if (ai > bi) { return 1; }
|
|
138
|
+
if (ai < bi) { return -1; }
|
|
139
|
+
i = i - 1;
|
|
140
|
+
}
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ── Multiply by small constant: c = a × k (k < 10000) ───────────────────────
|
|
145
|
+
// Max per-limb: 9999 × 9999 + 9999 = 99,989,999 < INT32 ✓
|
|
146
|
+
|
|
147
|
+
fn bigint_mul_small(k: int) {
|
|
148
|
+
let carry: int = 0;
|
|
149
|
+
let i: int = 0;
|
|
150
|
+
while (i < 8) {
|
|
151
|
+
let p: int = storage_get_int("rs:bigint", "a", i) * k + carry;
|
|
152
|
+
carry = p / 10000;
|
|
153
|
+
storage_set_int("rs:bigint", "c", i, p % 10000);
|
|
154
|
+
i = i + 1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ── Multiply: c = a × b (grade-school O(n²), n=8) ───────────────────────────
|
|
159
|
+
// Per-product max: 9999 × 9999 + 9999 (prev c) + 9999 (carry) = 99,999,999 < INT32 ✓
|
|
160
|
+
|
|
161
|
+
fn bigint_mul() {
|
|
162
|
+
storage_set_array("rs:bigint", "c", "[0,0,0,0,0,0,0,0]");
|
|
163
|
+
let i: int = 0;
|
|
164
|
+
while (i < 8) {
|
|
165
|
+
let ai: int = storage_get_int("rs:bigint", "a", i);
|
|
166
|
+
if (ai != 0) {
|
|
167
|
+
let j: int = 0;
|
|
168
|
+
let carry: int = 0;
|
|
169
|
+
while (j < 8) {
|
|
170
|
+
let k: int = i + j;
|
|
171
|
+
if (k < 8) {
|
|
172
|
+
let p: int = ai * storage_get_int("rs:bigint", "b", j)
|
|
173
|
+
+ storage_get_int("rs:bigint", "c", k)
|
|
174
|
+
+ carry;
|
|
175
|
+
carry = p / 10000;
|
|
176
|
+
storage_set_int("rs:bigint", "c", k, p % 10000);
|
|
177
|
+
}
|
|
178
|
+
j = j + 1;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
i = i + 1;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ── Fibonacci: F(n) → register a (n ≤ 150 before 32-digit overflow) ─────────
|
|
186
|
+
//
|
|
187
|
+
// Invariant: a=F(k), b=F(k+1). After n iterations: a=F(n).
|
|
188
|
+
//
|
|
189
|
+
// F(50) = 12,586,269,025 → a[0]=9025, a[1]=8626, a[2]=125
|
|
190
|
+
// F(100) = 354,224,848,179,261,915,075 → 21 digits, fits in 6 limbs
|
|
191
|
+
|
|
192
|
+
fn bigint_fib(n: int) {
|
|
193
|
+
bigint_init(); // a=0=F(0), b=0
|
|
194
|
+
bigint_from_int_b(1); // b=1=F(1)
|
|
195
|
+
let i: int = 0;
|
|
196
|
+
while (i < n) {
|
|
197
|
+
// Invariant entering iteration: a=F(i), b=F(i+1)
|
|
198
|
+
bigint_add(); // c = F(i) + F(i+1) = F(i+2)
|
|
199
|
+
bigint_copy_b_to_a(); // a = F(i+1)
|
|
200
|
+
bigint_copy_c_to_b(); // b = F(i+2)
|
|
201
|
+
// Invariant restored: a=F(i+1), b=F(i+2)
|
|
202
|
+
i = i + 1;
|
|
203
|
+
}
|
|
204
|
+
// result: a = F(n)
|
|
205
|
+
}
|
package/src/stdlib/math.mcrs
CHANGED
|
@@ -71,16 +71,29 @@ fn lerp(a: int, b: int, t: int) -> int {
|
|
|
71
71
|
// Uses Newton's method, converges in ≤16 iterations for all int32.
|
|
72
72
|
// isqrt(9) == 3, isqrt(10) == 3, isqrt(0) == 0
|
|
73
73
|
fn isqrt(n: int) -> int {
|
|
74
|
-
if (n <= 0) {
|
|
75
|
-
|
|
74
|
+
if (n <= 0) { return 0; }
|
|
75
|
+
if (n == 1) { return 1; }
|
|
76
|
+
// Bit-length of n: how many bits needed to represent n.
|
|
77
|
+
let bits: int = 0;
|
|
78
|
+
let tmp: int = n;
|
|
79
|
+
while (tmp > 0) {
|
|
80
|
+
tmp = tmp / 2;
|
|
81
|
+
bits = bits + 1;
|
|
76
82
|
}
|
|
77
|
-
|
|
83
|
+
// Initial guess: 2^((bits+1)/2). Always ≥ sqrt(n), so Newton converges
|
|
84
|
+
// monotonically from above — the standard floor-sqrt Newton iteration.
|
|
85
|
+
let half: int = (bits + 1) / 2;
|
|
86
|
+
let x: int = 1;
|
|
87
|
+
let j: int = 0;
|
|
88
|
+
while (j < half) {
|
|
89
|
+
x = x * 2;
|
|
90
|
+
j = j + 1;
|
|
91
|
+
}
|
|
92
|
+
// Newton–Raphson floor-sqrt: converges in ≤ 8 iterations from a 2× overestimate.
|
|
78
93
|
let i: int = 0;
|
|
79
94
|
while (i < 16) {
|
|
80
95
|
let next: int = (x + n / x) / 2;
|
|
81
|
-
if (next >= x) {
|
|
82
|
-
return x;
|
|
83
|
-
}
|
|
96
|
+
if (next >= x) { return x; }
|
|
84
97
|
x = next;
|
|
85
98
|
i = i + 1;
|
|
86
99
|
}
|