bigint: Prepare for multiplication.

This commit is contained in:
Jeroen van Rijn
2021-08-11 20:59:50 +02:00
parent daceaa65f5
commit dfd5a993a2
2 changed files with 53 additions and 11 deletions
+23 -8
View File
@@ -19,14 +19,20 @@ when _LOW_MEMORY {
_DEFAULT_DIGIT_COUNT :: 32; _DEFAULT_DIGIT_COUNT :: 32;
} }
// /* tunable cutoffs */ _MUL_KARATSUBA_CUTOFF :: #config(MUL_KARATSUBA_CUTOFF, _DEFAULT_MUL_KARATSUBA_CUTOFF);
// #ifndef MP_FIXED_CUTOFFS _SQR_KARATSUBA_CUTOFF :: #config(SQR_KARATSUBA_CUTOFF, _DEFAULT_SQR_KARATSUBA_CUTOFF);
// extern int _MUL_TOOM_CUTOFF :: #config(MUL_TOOM_CUTOFF, _DEFAULT_MUL_TOOM_CUTOFF);
// MP_MUL_KARATSUBA_CUTOFF, _SQR_TOOM_CUTOFF :: #config(SQR_TOOM_CUTOFF, _DEFAULT_SQR_TOOM_CUTOFF);
// MP_SQR_KARATSUBA_CUTOFF,
// MP_MUL_TOOM_CUTOFF, /*
// MP_SQR_TOOM_CUTOFF; These defaults were tuned on an AMD A8-6600K (64-bit) using libTomMath's `make tune`.
// #endif 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 { Sign :: enum u8 {
Zero_or_Positive = 0, Zero_or_Positive = 0,
@@ -94,15 +100,24 @@ when size_of(rawptr) == 8 {
DIGIT :: distinct(u64); DIGIT :: distinct(u64);
_DIGIT_BITS :: 60; _DIGIT_BITS :: 60;
_WORD :: u128; _WORD :: u128;
_MAX_COMBA :: 1 << (128 - (2 * _DIGIT_BITS)) ;
_WARRAY :: 1 << ((128 - (2 * _DIGIT_BITS)) + 1);
} else { } else {
DIGIT :: distinct(u32); DIGIT :: distinct(u32);
_DIGIT_BITS :: 28; _DIGIT_BITS :: 28;
_WORD :: u64; _WORD :: u64;
_MAX_COMBA :: 1 << ( 64 - (2 * _DIGIT_BITS)) ;
_WARRAY :: 1 << (( 64 - (2 * _DIGIT_BITS)) + 1);
} }
#assert(size_of(_WORD) == 2 * size_of(DIGIT)); #assert(size_of(_WORD) == 2 * size_of(DIGIT));
_MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1); _MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1);
_DIGIT_MAX :: _MASK; _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 { Order :: enum i8 {
LSB_First = -1, LSB_First = -1,
MSB_First = 1, MSB_First = 1,
+30 -3
View File
@@ -13,6 +13,34 @@ package bigint
import "core:fmt" import "core:fmt"
import "core:mem" 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 { print_int :: proc(a: ^Int, print_raw := false) -> string {
if print_raw { if print_raw {
return fmt.tprintf("%v", a); return fmt.tprintf("%v", a);
@@ -44,7 +72,7 @@ demo :: proc() {
fmt.printf("c: %v\n", print_int(c, true)); fmt.printf("c: %v\n", print_int(c, true));
fmt.println("=== Add ==="); fmt.println("=== Add ===");
err = sub(a, a, DIGIT(42)); err = sub(c, a, b);
// err = add(c, a, b); // err = add(c, a, b);
fmt.printf("Error: %v\n", err); fmt.printf("Error: %v\n", err);
fmt.printf("a: %v\n", print_int(a)); fmt.printf("a: %v\n", print_int(a));
@@ -57,8 +85,7 @@ main :: proc() {
mem.tracking_allocator_init(&ta, context.allocator); mem.tracking_allocator_init(&ta, context.allocator);
context.allocator = mem.tracking_allocator(&ta); 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(); demo();
if len(ta.allocation_map) > 0 { if len(ta.allocation_map) > 0 {