mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-17 16:38:22 +00:00
bigint: itoa now writes backwards directly, no need to reverse after.
This commit is contained in:
@@ -58,12 +58,18 @@ demo :: proc() {
|
||||
fmt.printf("b: %s, err: %v\n\n", bs, err);
|
||||
delete(bs);
|
||||
|
||||
c, err = init();
|
||||
c, err = init(-4);
|
||||
defer destroy(c);
|
||||
cs, err = itoa(c);
|
||||
fmt.printf("b: %s, err: %v\n\n", cs, err);
|
||||
fmt.printf("c: %s, err: %v\n\n", cs, err);
|
||||
delete(cs);
|
||||
|
||||
cstr: cstring;
|
||||
defer delete(cstr);
|
||||
|
||||
cstr, err = itoa_cstring(a);
|
||||
fmt.printf("cstring: %v, err: %v\n\n", cstr, err);
|
||||
|
||||
fmt.println("=== Add ===");
|
||||
err = sub(c, a, b);
|
||||
|
||||
|
||||
@@ -103,13 +103,19 @@ itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocator) -
|
||||
|
||||
Use `radix_size` or `radix_size_estimate` to determine a buffer size big enough.
|
||||
|
||||
`written` includes the sign if negative, and the zero terminator if asked for.
|
||||
If you want a 2s complement negative number, adjust it before calling.
|
||||
|
||||
You can pass the output of `radix_size` to `size` if you've previously called it to size
|
||||
the output buffer. If you haven't, this routine will call it. This way it knows if the buffer
|
||||
is the appropriate size, and it can avoid writing backwards and then reversing.
|
||||
is the appropriate size, and we can write directly in place without a reverse step at the end.
|
||||
|
||||
=== === === IMPORTANT === === ===
|
||||
|
||||
If you determined the buffer size using `radix_size_estimate`, or have a buffer
|
||||
that you reuse that you know is large enough, don't pass this size unless you know what you are doing,
|
||||
because we will always write backwards starting at last byte of the buffer.
|
||||
|
||||
Keep in mind that if you set `size` yourself and it's smaller than the buffer,
|
||||
it'll result in buffer overflows, as we use it to avoid reversing at the end
|
||||
and having to perform a buffer overflow check each character.
|
||||
*/
|
||||
itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_terminate := false) -> (written: int, err: Error) {
|
||||
assert_initialized(a); size := size;
|
||||
@@ -145,17 +151,20 @@ itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_termina
|
||||
return 0, .Buffer_Overflow;
|
||||
}
|
||||
|
||||
if is_neg(a) {
|
||||
buffer[written] = '-';
|
||||
written += 1;
|
||||
if zero_terminate {
|
||||
available -= 1;
|
||||
buffer[available] = 0;
|
||||
written += 1;
|
||||
}
|
||||
|
||||
buffer[written] = RADIX_TABLE[a.digit[0]];
|
||||
written += 1;
|
||||
available -= 1;
|
||||
buffer[available] = RADIX_TABLE[a.digit[0]];
|
||||
written += 1;
|
||||
|
||||
if zero_terminate {
|
||||
buffer[written] = 0;
|
||||
written += 1;
|
||||
if is_neg(a) {
|
||||
available -= 1;
|
||||
buffer[available] = '-';
|
||||
written += 1;
|
||||
}
|
||||
|
||||
return written, .OK;
|
||||
@@ -165,6 +174,15 @@ itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_termina
|
||||
Fast path for when `Int` fits within a `_WORD`.
|
||||
*/
|
||||
if a.used == 1 || a.used == 2 {
|
||||
if zero_terminate {
|
||||
if available == 0 {
|
||||
return written, .Buffer_Overflow;
|
||||
}
|
||||
available -= 1;
|
||||
buffer[available] = 0;
|
||||
written += 1;
|
||||
}
|
||||
|
||||
val := _WORD(a.digit[1]) << _DIGIT_BITS + _WORD(a.digit[0]);
|
||||
for val > 0 {
|
||||
if available == 0 {
|
||||
@@ -172,8 +190,8 @@ itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_termina
|
||||
}
|
||||
|
||||
q := val / _WORD(radix);
|
||||
buffer[written] = RADIX_TABLE[val - (q * _WORD(radix))];
|
||||
available -= 1;
|
||||
buffer[available] = RADIX_TABLE[val - (q * _WORD(radix))];
|
||||
written += 1;
|
||||
|
||||
val = q;
|
||||
@@ -182,19 +200,8 @@ itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_termina
|
||||
if available == 0 {
|
||||
return written, .Buffer_Overflow;
|
||||
}
|
||||
buffer[written] = '-';
|
||||
available -= 1;
|
||||
written += 1;
|
||||
}
|
||||
/*
|
||||
Reverse output.
|
||||
*/
|
||||
slice.reverse(buffer[:written]);
|
||||
if zero_terminate {
|
||||
if available == 0 {
|
||||
return written, .Buffer_Overflow;
|
||||
}
|
||||
buffer[written] = 0;
|
||||
buffer[available] = '-';
|
||||
written += 1;
|
||||
}
|
||||
return written, .OK;
|
||||
|
||||
Reference in New Issue
Block a user