mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 11:52:22 -07:00
big: fix itoa base PoT other than 16.
This commit is contained in:
@@ -76,7 +76,6 @@ demo :: proc() {
|
||||
defer destroy(destination, source, quotient, remainder, numerator, denominator);
|
||||
|
||||
err = rand(destination, 120, r);
|
||||
// print("destination", destination, 10);
|
||||
for _ in 0 ..< 10_000 {
|
||||
if err != .None {
|
||||
fmt.printf("set error: %v\n", err);
|
||||
@@ -85,7 +84,7 @@ demo :: proc() {
|
||||
as, err = itoa(destination, 16);
|
||||
e := time.tick_since(s);
|
||||
Timings[.itoa].t += e; Timings[.itoa].c += 1;
|
||||
assert(as == "B38677A01B8EF75CF434CA68677495", as);
|
||||
//assert(as == "ADCC737B67B0FCD7F189074CBE088B718141A383F9CF09B4D3824A09A3AEBAC155B810C29D62385F8F85616794C25393A757CEDEEBE3B0FE24573894DF7842A76F543D64A78FFD24D325CE044E9A0F69DE00CFFCC41427170096BC6D3537C856CD930A3794F03DB558CD5DB6A65971E618C5D0DBAE1E7AF52DDB8F5F84CD5BFC0B2EEEDBFB70E6B38677A01B8EF75CF434CA68677495", as);
|
||||
delete(as);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +103,7 @@ main :: proc() {
|
||||
if v.c > 0 {
|
||||
avg := time.duration_milliseconds(time.Duration(f64(v.t) / f64(v.c)));
|
||||
total := time.duration_milliseconds(time.Duration(v.t));
|
||||
fmt.printf("%v: %.3f ms (avg), %.3f (total, %v calls)\n", i, avg, total, v.c);
|
||||
fmt.printf("%v: %.3f ms (avg), %.3f ms (total, %v calls)\n", i, avg, total, v.c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-29
@@ -177,7 +177,7 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
|
||||
/*
|
||||
Helpers to extract values from the `Int`.
|
||||
*/
|
||||
int_extract_bit :: proc(a: ^Int, bit_offset: int) -> (bit: DIGIT, err: Error) {
|
||||
extract_bit :: proc(a: ^Int, bit_offset: int) -> (bit: DIGIT, err: Error) {
|
||||
/*
|
||||
Check that `a`is usable.
|
||||
*/
|
||||
@@ -195,6 +195,9 @@ int_extract_bit :: proc(a: ^Int, bit_offset: int) -> (bit: DIGIT, err: Error) {
|
||||
return 1 if ((a.digit[limb] & i) != 0) else 0, .None;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Optimize.
|
||||
*/
|
||||
int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: Error) {
|
||||
/*
|
||||
Check that `a`is usable.
|
||||
@@ -207,40 +210,57 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
|
||||
return 0, .Invalid_Argument;
|
||||
}
|
||||
|
||||
limb_lo := offset / _DIGIT_BITS;
|
||||
bits_lo := offset % _DIGIT_BITS;
|
||||
limb_hi := (offset + count) / _DIGIT_BITS;
|
||||
bits_hi := (offset + count) % _DIGIT_BITS;
|
||||
when true {
|
||||
v: DIGIT;
|
||||
e: Error;
|
||||
|
||||
if limb_lo < 0 || limb_lo >= a.used || limb_hi < 0 || limb_hi >= a.used {
|
||||
return 0, .Invalid_Argument;
|
||||
}
|
||||
|
||||
for i := limb_hi; i >= limb_lo; i -= 1 {
|
||||
res <<= _DIGIT_BITS;
|
||||
|
||||
/*
|
||||
Determine which bits to extract from each DIGIT. The whole DIGIT's worth by default.
|
||||
*/
|
||||
bit_count := _DIGIT_BITS;
|
||||
bit_offset := 0;
|
||||
if i == limb_lo {
|
||||
bit_count -= bits_lo;
|
||||
bit_offset = _DIGIT_BITS - bit_count;
|
||||
} else if i == limb_hi {
|
||||
bit_count = bits_hi;
|
||||
bit_offset = 0;
|
||||
for shift := 0; shift < count; shift += 1 {
|
||||
o := offset + shift;
|
||||
v, e = extract_bit(a, o);
|
||||
if e != .None {
|
||||
break;
|
||||
}
|
||||
res = res + _WORD(v) << uint(shift);
|
||||
}
|
||||
|
||||
d := a.digit[i];
|
||||
return res, e;
|
||||
} else {
|
||||
limb_lo := offset / _DIGIT_BITS;
|
||||
bits_lo := offset % _DIGIT_BITS;
|
||||
limb_hi := (offset + count) / _DIGIT_BITS;
|
||||
bits_hi := (offset + count) % _DIGIT_BITS;
|
||||
|
||||
v := (d >> uint(bit_offset)) & DIGIT(1 << uint(bit_count - 1));
|
||||
m := DIGIT(1 << uint(bit_count-1));
|
||||
r := v & m;
|
||||
if limb_lo < 0 || limb_lo >= a.used || limb_hi < 0 || limb_hi >= a.used {
|
||||
return 0, .Invalid_Argument;
|
||||
}
|
||||
|
||||
for i := limb_hi; i >= limb_lo; i -= 1 {
|
||||
res <<= _DIGIT_BITS;
|
||||
|
||||
/*
|
||||
Determine which bits to extract from each DIGIT. The whole DIGIT's worth by default.
|
||||
*/
|
||||
bit_count := _DIGIT_BITS;
|
||||
bit_offset := 0;
|
||||
if i == limb_lo {
|
||||
bit_count -= bits_lo;
|
||||
bit_offset = _DIGIT_BITS - bit_count;
|
||||
} else if i == limb_hi {
|
||||
bit_count = bits_hi;
|
||||
bit_offset = 0;
|
||||
}
|
||||
|
||||
d := a.digit[i];
|
||||
|
||||
v := (d >> uint(bit_offset)) & DIGIT(1 << uint(bit_count - 1));
|
||||
m := DIGIT(1 << uint(bit_count-1));
|
||||
r := v & m;
|
||||
|
||||
res |= _WORD(r);
|
||||
}
|
||||
return res, .None;
|
||||
|
||||
res |= _WORD(r);
|
||||
}
|
||||
return res, .None;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -200,7 +200,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
|
||||
count, err = count_bits(a);
|
||||
digit: _WORD;
|
||||
|
||||
for offset := 0; offset < count; offset += 4 {
|
||||
for offset := 0; offset < count; offset += shift {
|
||||
bits_to_get := int(min(count - offset, shift));
|
||||
if digit, err = int_bitfield_extract(a, offset, bits_to_get); err != .None {
|
||||
return len(buffer) - available, .Invalid_Argument;
|
||||
|
||||
Reference in New Issue
Block a user