mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
big: ZII.
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user