mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
bigint: Add count_bits and more prep.
This commit is contained in:
@@ -89,7 +89,6 @@ add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
|
|||||||
If `a` is negative and `|a|` >= `digit`, call `dest = |a| - digit`
|
If `a` is negative and `|a|` >= `digit`, call `dest = |a| - digit`
|
||||||
*/
|
*/
|
||||||
if is_neg(a) && (a.used > 1 || a.digit[0] >= digit) {
|
if is_neg(a) && (a.used > 1 || a.digit[0] >= digit) {
|
||||||
fmt.print("a = neg, %v\n", print_int(a));
|
|
||||||
/*
|
/*
|
||||||
Temporarily fix `a`'s sign.
|
Temporarily fix `a`'s sign.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ package bigint
|
|||||||
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
|
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import "core:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tunables
|
Tunables
|
||||||
*/
|
*/
|
||||||
@@ -97,26 +99,23 @@ when size_of(rawptr) == 8 {
|
|||||||
/*
|
/*
|
||||||
We can use u128 as an intermediary.
|
We can use u128 as an intermediary.
|
||||||
*/
|
*/
|
||||||
DIGIT :: distinct(u64);
|
DIGIT :: distinct(u64);
|
||||||
_DIGIT_BITS :: 60;
|
_WORD :: distinct(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;
|
_WORD :: distinct(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);
|
|
||||||
_DIGIT_MAX :: _MASK;
|
|
||||||
|
|
||||||
_BITS_IN_BYTE :: 8;
|
_DIGIT_TYPE_BITS :: 8 * size_of(DIGIT);
|
||||||
_BITS_IN_TYPE :: #force_inline proc($T) -> int where intrinsics.type_is_integer(T) {
|
_WORD_TYPE_BITS :: 8 * size_of(_WORD);
|
||||||
return _BITS_IN_BYTE * size_of(T);
|
|
||||||
}
|
_DIGIT_BITS :: _DIGIT_TYPE_BITS - 4;
|
||||||
|
|
||||||
|
_MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1);
|
||||||
|
_DIGIT_MAX :: _MASK;
|
||||||
|
_MAX_COMBA :: 1 << (_WORD_TYPE_BITS - (2 * _DIGIT_BITS)) ;
|
||||||
|
_WARRAY :: 1 << ((_WORD_TYPE_BITS - (2 * _DIGIT_BITS)) + 1);
|
||||||
|
|
||||||
Order :: enum i8 {
|
Order :: enum i8 {
|
||||||
LSB_First = -1,
|
LSB_First = -1,
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ demo :: proc() {
|
|||||||
err = sub(c, a, b);
|
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, bits: %v\n", print_int(a), count_bits(a));
|
||||||
fmt.printf("b: %v\n", print_int(b));
|
fmt.printf("b: %v, bits: %v\n", print_int(b), count_bits(b));
|
||||||
fmt.printf("c: %v\n", print_int(c));
|
fmt.printf("c: %v, bits: %v\n", print_int(c), count_bits(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
|||||||
@@ -217,6 +217,29 @@ minus_one :: proc(a: ^Int, minimize := false) -> (err: Error) {
|
|||||||
return .OK;
|
return .OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Count bits in an `Int`.
|
||||||
|
*/
|
||||||
|
count_bits :: proc(a: ^Int) -> (count: int) {
|
||||||
|
assert_initialized(a);
|
||||||
|
/*
|
||||||
|
Fast path for zero.
|
||||||
|
*/
|
||||||
|
if is_zero(a) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Get the number of DIGITs and use it.
|
||||||
|
*/
|
||||||
|
count = (a.used - 1) * _DIGIT_BITS;
|
||||||
|
/*
|
||||||
|
Take the last DIGIT and count the bits in it.
|
||||||
|
*/
|
||||||
|
clz := int(intrinsics.count_leading_zeros(a.digit[a.used - 1]));
|
||||||
|
count += (_DIGIT_TYPE_BITS - clz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Internal helpers.
|
Internal helpers.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user