big: ZII.

This commit is contained in:
Jeroen van Rijn
2021-08-11 20:59:50 +02:00
parent 4eadd0867d
commit 687c211a58
3 changed files with 25 additions and 30 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ package big
import "core:intrinsics" import "core:intrinsics"
int_is_initialized :: proc(a: ^Int) -> bool { int_is_initialized :: proc(a: ^Int) -> bool {
return a != rawptr(uintptr(0)); return a != rawptr(uintptr(0)) && a.allocated >= _MIN_DIGIT_COUNT;
} }
int_is_zero :: proc(a: ^Int) -> bool { int_is_zero :: proc(a: ^Int) -> bool {
+4 -6
View File
@@ -53,18 +53,16 @@ print :: proc(name: string, a: ^Int, base := i8(16)) {
} }
demo :: proc() { demo :: proc() {
a, b, c: ^Int; a, b, c := &Int{}, &Int{}, &Int{};
err: Error; err: Error;
defer destroy(a); defer destroy(a);
defer destroy(b); defer destroy(b);
defer destroy(c); defer destroy(c);
a, err = init(512); err = set(a, 512);
err = init(b, a);
b, err = init(a); err = init(c, -4);
c, err = init(-4);
print("a", a, 2); print("a", a, 2);
print("b", b, 2); print("b", b, 2);
+20 -23
View File
@@ -11,7 +11,7 @@ package big
import "core:mem" import "core:mem"
import "core:intrinsics" import "core:intrinsics"
//import "core:fmt"
/* /*
Deallocates the backing memory of an `Int`. Deallocates the backing memory of an `Int`.
*/ */
@@ -24,7 +24,6 @@ int_destroy :: proc(a: ^Int, allocator_zeroes := false, allocator := context.all
free(&a.digit[0]); free(&a.digit[0]);
a.used = 0; a.used = 0;
a.allocated = 0; a.allocated = 0;
free(a);
} }
/* /*
@@ -32,57 +31,52 @@ int_destroy :: proc(a: ^Int, allocator_zeroes := false, allocator := context.all
Size is the last parameter so it doesn't conflict with `int_init_from_integer`, Size is the last parameter so it doesn't conflict with `int_init_from_integer`,
and we can say `init(512)` to init & set to 512. and we can say `init(512)` to init & set to 512.
*/ */
int_init_sized :: proc(allocator_zeroes := true, allocator := context.allocator, size := _DEFAULT_DIGIT_COUNT) -> (a: ^Int, err: Error) { int_init_sized :: proc(a: ^Int, allocator_zeroes := true, allocator := context.allocator, size := _DEFAULT_DIGIT_COUNT) -> (err: Error) {
/* /*
Allocating a new variable. Allocating a new variable.
*/ */
a = new(Int, allocator);
a.digit = mem.make_dynamic_array_len_cap([dynamic]DIGIT, size, size, allocator); a.digit = mem.make_dynamic_array_len_cap([dynamic]DIGIT, size, size, allocator);
a.allocated = 0; a.allocated = 0;
a.used = 0; a.used = 0;
a.sign = .Zero_or_Positive; a.sign = .Zero_or_Positive;
if len(a.digit) != int(size) { if len(a.digit) != size {
return a, .Out_of_Memory; return .Out_of_Memory;
} }
a.allocated = int(size); a.allocated = size;
if !allocator_zeroes { if !allocator_zeroes {
_zero_unused(a); _zero_unused(a);
} }
return a, .OK; return .OK;
} }
/* /*
Initialize from a signed or unsigned platform integer. Initialize from a signed or unsigned platform integer.
Inits a new `Int` and then calls the appropriate `set` routine. Inits a new `Int` and then calls the appropriate `set` routine.
*/ */
int_init_from_integer :: proc(src: $T, minimize := false, allocator_zeroes := true, allocator := context.allocator) -> (a: ^Int, err: Error) where intrinsics.type_is_integer(T) { int_init_from_integer :: proc(a: ^Int, src: $T, minimize := false, allocator_zeroes := true, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) {
n := _DEFAULT_DIGIT_COUNT; n := _DEFAULT_DIGIT_COUNT;
if minimize { if minimize {
n = _MIN_DIGIT_COUNT; n = _MIN_DIGIT_COUNT;
} }
a, err = init(allocator_zeroes, allocator, n); return set(a, src, minimize);
if err == .OK {
set(a, src, minimize);
}
return;
} }
/* /*
Initialize an `Int` as a copy from another `Int`. Initialize an `Int` as a copy from another `Int`.
*/ */
int_init_copy :: proc(src: ^Int, minimize := false, allocator_zeroes := true, allocator := context.allocator) -> (a: ^Int, err: Error) { int_init_copy :: proc(dest, src: ^Int, minimize := false, allocator_zeroes := true, allocator := context.allocator) -> (err: Error) {
if !is_initialized(src) { if !is_initialized(src) {
return nil, .Invalid_Input; return .Invalid_Input;
} }
a, err = init(allocator_zeroes, allocator, src.used);
if err == .OK { if err == .OK {
copy(a, src); err = copy(dest, src);
} }
return; return;
} }
@@ -90,9 +84,12 @@ int_init_copy :: proc(src: ^Int, minimize := false, allocator_zeroes := true, al
/* /*
Helpers to set an `Int` to a specific value. Helpers to set an `Int` to a specific value.
*/ */
int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, loc := #caller_location) where intrinsics.type_is_integer(T) { int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator_zeroes := true, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) {
src := src; src := src;
assert_initialized(dest, loc); if !is_initialized(dest) {
grow(dest, _DEFAULT_DIGIT_COUNT);
}
dest.used = 0; dest.used = 0;
dest.sign = .Zero_or_Positive if src >= 0 else .Negative; dest.sign = .Zero_or_Positive if src >= 0 else .Negative;
@@ -107,6 +104,7 @@ int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, loc := #cal
shrink(dest); shrink(dest);
} }
_zero_unused(dest); _zero_unused(dest);
return .OK;
} }
set :: proc{int_set_from_integer}; set :: proc{int_set_from_integer};
@@ -123,9 +121,9 @@ copy :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
} }
/* /*
Check they're both initialized. Check `src` is initialized.
*/ */
if !(is_initialized(dest) && is_initialized(src)) { if !is_initialized(src) {
return .Invalid_Input; return .Invalid_Input;
} }
@@ -270,7 +268,6 @@ shrink :: proc(a: ^Int) -> (err: Error) {
} }
grow :: proc(a: ^Int, n: int, allow_shrink := false) -> (err: Error) { grow :: proc(a: ^Int, n: int, allow_shrink := false) -> (err: Error) {
assert_initialized(a);
/* /*
By default, calling `grow` with `n` <= a.allocated won't resize. By default, calling `grow` with `n` <= a.allocated won't resize.
With `allow_shrink` set to `true`, will call resize and shrink the `Int` as a result. With `allow_shrink` set to `true`, will call resize and shrink the `Int` as a result.