Skip to content

Commit

Permalink
Merge pull request #42 from lenawanel/master
Browse files Browse the repository at this point in the history
fix unsingned integer formatting for large enough u64s
  • Loading branch information
NotAFlyingGoose authored Jul 9, 2024
2 parents b638500 + ea4d5ac commit 33204bd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
23 changes: 16 additions & 7 deletions core/src/fmt.capy
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,22 @@ i64_to_string :: (n: i64) -> StringBuilder {
}

u64_to_string :: (n: u64) -> StringBuilder {
str := string_builder.make_with_capacity(39);

new_len := _write_i64_to_buf(n as i64, false, str.buf as ^mut any as ^mut u8, 0, 0);

str.len = new_len;

string_builder.shrink_to_fit(^mut str);
n := n;
digits := core.math.lg_u64(n) + 1;
str := string_builder.make_with_capacity(digits);
str.len = digits;

while digits > 0 {
remainder :: n % 10;
n = n / 10;
digits = digits - 1;

ptr.write(
str.buf,
('0' as u8 + remainder) as u8,
digits
);
}

str
}
Expand Down
36 changes: 36 additions & 0 deletions core/src/math.capy
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,39 @@ next_pow_of_two :: (x: usize) -> usize {
is_NaN :: (n: f64) -> bool {
n != n
}

// logarithm base 2 of unsigned 64 bit integers
// TODO: use cranelift intrinsic for this
// returns 0 if n == 0
log2_u64 :: (n: u64) -> u64 {
n := n;
i := 0;
if n == 0 { return 0; }
while n != 1 {
n = n >> 1;
i = i + 1 as u64;
}
i
}

// logarithm base 10 of unsigned 64 bit integers
// returns 0 if n == 0
lg_u64 :: (n: u64) -> u64 {
pows_of_10 :: comptime {
arr : [20] u64;
i := 0;
pow := 1;

while i <= 19 {
arr[i] = pow;
pow = 10 * pow;
i = i + 1;
}

arr
};
if n == 0 { return 0; }

t :: (((log2_u64(n) + 1) * 1233) >> 12);
t - (n < pows_of_10[t]) as u64
}

0 comments on commit 33204bd

Please sign in to comment.