aboutsummaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-07-17 00:03:40 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-08-11 20:59:50 +0200
commitdfd5a993a28c404d2b6f5b06ab6c3663b40cf3de (patch)
treeab9e32e5905f0eb270fb422d4aa0d6879413a823 /core/math
parentdaceaa65f553556d18aa908e5a8b3512f4b73ddf (diff)
bigint: Prepare for multiplication.
Diffstat (limited to 'core/math')
-rw-r--r--core/math/bigint/bigint.odin31
-rw-r--r--core/math/bigint/example.odin33
2 files changed, 53 insertions, 11 deletions
diff --git a/core/math/bigint/bigint.odin b/core/math/bigint/bigint.odin
index 1445bc69d..6e146b0cb 100644
--- a/core/math/bigint/bigint.odin
+++ b/core/math/bigint/bigint.odin
@@ -19,14 +19,20 @@ when _LOW_MEMORY {
_DEFAULT_DIGIT_COUNT :: 32;
}
-// /* tunable cutoffs */
-// #ifndef MP_FIXED_CUTOFFS
-// extern int
-// MP_MUL_KARATSUBA_CUTOFF,
-// MP_SQR_KARATSUBA_CUTOFF,
-// MP_MUL_TOOM_CUTOFF,
-// MP_SQR_TOOM_CUTOFF;
-// #endif
+_MUL_KARATSUBA_CUTOFF :: #config(MUL_KARATSUBA_CUTOFF, _DEFAULT_MUL_KARATSUBA_CUTOFF);
+_SQR_KARATSUBA_CUTOFF :: #config(SQR_KARATSUBA_CUTOFF, _DEFAULT_SQR_KARATSUBA_CUTOFF);
+_MUL_TOOM_CUTOFF :: #config(MUL_TOOM_CUTOFF, _DEFAULT_MUL_TOOM_CUTOFF);
+_SQR_TOOM_CUTOFF :: #config(SQR_TOOM_CUTOFF, _DEFAULT_SQR_TOOM_CUTOFF);
+
+/*
+ These defaults were tuned on an AMD A8-6600K (64-bit) using libTomMath's `make tune`.
+ TODO(Jeroen): Port this tuning algorithm and tune them for more modern processors.
+*/
+_DEFAULT_MUL_KARATSUBA_CUTOFF :: 80;
+_DEFAULT_SQR_KARATSUBA_CUTOFF :: 120;
+_DEFAULT_MUL_TOOM_CUTOFF :: 350;
+_DEFAULT_SQR_TOOM_CUTOFF :: 400;
+
Sign :: enum u8 {
Zero_or_Positive = 0,
@@ -94,15 +100,24 @@ when size_of(rawptr) == 8 {
DIGIT :: distinct(u64);
_DIGIT_BITS :: 60;
_WORD :: u128;
+ _MAX_COMBA :: 1 << (128 - (2 * _DIGIT_BITS)) ;
+ _WARRAY :: 1 << ((128 - (2 * _DIGIT_BITS)) + 1);
} else {
DIGIT :: distinct(u32);
_DIGIT_BITS :: 28;
_WORD :: u64;
+ _MAX_COMBA :: 1 << ( 64 - (2 * _DIGIT_BITS)) ;
+ _WARRAY :: 1 << (( 64 - (2 * _DIGIT_BITS)) + 1);
}
#assert(size_of(_WORD) == 2 * size_of(DIGIT));
_MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1);
_DIGIT_MAX :: _MASK;
+_BITS_IN_BYTE :: 8;
+_BITS_IN_TYPE :: #force_inline proc($T) -> int where intrinsics.type_is_integer(T) {
+ return _BITS_IN_BYTE * size_of(T);
+}
+
Order :: enum i8 {
LSB_First = -1,
MSB_First = 1,
diff --git a/core/math/bigint/example.odin b/core/math/bigint/example.odin
index 69dab47dd..082e695c3 100644
--- a/core/math/bigint/example.odin
+++ b/core/math/bigint/example.odin
@@ -13,6 +13,34 @@ package bigint
import "core:fmt"
import "core:mem"
+print_configation :: proc() {
+ fmt.printf(
+`Configuration:
+ DIGIT_BITS %v
+ MIN_DIGIT_COUNT %v
+ MAX_DIGIT_COUNT %v
+ EFAULT_DIGIT_COUNT %v
+ MAX_COMBA %v
+ WARRAY %v
+ MUL_KARATSUBA_CUTOFF %v
+ SQR_KARATSUBA_CUTOFF %v
+ MUL_TOOM_CUTOFF %v
+ SQR_TOOM_CUTOFF %v
+`, _DIGIT_BITS,
+_MIN_DIGIT_COUNT,
+_MAX_DIGIT_COUNT,
+_DEFAULT_DIGIT_COUNT,
+_MAX_COMBA,
+_WARRAY,
+_MUL_KARATSUBA_CUTOFF,
+_SQR_KARATSUBA_CUTOFF,
+_MUL_TOOM_CUTOFF,
+_SQR_TOOM_CUTOFF,
+);
+
+ fmt.println();
+}
+
print_int :: proc(a: ^Int, print_raw := false) -> string {
if print_raw {
return fmt.tprintf("%v", a);
@@ -44,7 +72,7 @@ demo :: proc() {
fmt.printf("c: %v\n", print_int(c, true));
fmt.println("=== Add ===");
- err = sub(a, a, DIGIT(42));
+ err = sub(c, a, b);
// err = add(c, a, b);
fmt.printf("Error: %v\n", err);
fmt.printf("a: %v\n", print_int(a));
@@ -57,8 +85,7 @@ main :: proc() {
mem.tracking_allocator_init(&ta, context.allocator);
context.allocator = mem.tracking_allocator(&ta);
- fmt.printf("_DIGIT_BITS: %v\n_MIN_DIGIT_COUNT: %v\n_MAX_DIGIT_COUNT: %v\n_DEFAULT_DIGIT_COUNT: %v\n\n", _DIGIT_BITS, _MIN_DIGIT_COUNT, _MAX_DIGIT_COUNT, _DEFAULT_DIGIT_COUNT);
-
+ // print_configation();
demo();
if len(ta.allocation_map) > 0 {