mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-01 02:42:09 +00:00
Merge pull request #4107 from Feoramund/add-digit-count
Add `core:math.count_digits_of_base`
This commit is contained in:
@@ -2443,6 +2443,36 @@ hypot :: proc{
|
||||
hypot_f64, hypot_f64le, hypot_f64be,
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
count_digits_of_base :: proc "contextless" (value: $T, $base: int) -> (digits: int) where intrinsics.type_is_integer(T) {
|
||||
#assert(base >= 2, "base must be 2 or greater.")
|
||||
|
||||
value := value
|
||||
when !intrinsics.type_is_unsigned(T) {
|
||||
value = abs(value)
|
||||
}
|
||||
|
||||
when base == 2 {
|
||||
digits = max(1, 8 * size_of(T) - int(intrinsics.count_leading_zeros(value)))
|
||||
} else when intrinsics.count_ones(base) == 1 {
|
||||
free_bits := 8 * size_of(T) - int(intrinsics.count_leading_zeros(value))
|
||||
digits, free_bits = divmod(free_bits, intrinsics.constant_log2(base))
|
||||
if free_bits > 0 {
|
||||
digits += 1
|
||||
}
|
||||
digits = max(1, digits)
|
||||
} else {
|
||||
digits = 1
|
||||
base := cast(T)base
|
||||
for value >= base {
|
||||
value /= base
|
||||
digits += 1
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
F16_DIG :: 3
|
||||
F16_EPSILON :: 0.00097656
|
||||
F16_GUARD :: 0
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package test_core_math
|
||||
|
||||
import "core:math"
|
||||
import "core:strconv"
|
||||
import "core:testing"
|
||||
|
||||
@test
|
||||
@@ -1229,4 +1230,37 @@ test_large_tan :: proc(t: ^testing.T) {
|
||||
f2 := math.tan(vf[i] + large)
|
||||
testing.expectf(t, close(t, f1, f2), "math.tan(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_count_digits :: proc(t: ^testing.T) {
|
||||
_run_test :: proc(t: ^testing.T, $base: int) {
|
||||
buf: [64]u8
|
||||
for n in 0..<i64(base*base*base) {
|
||||
count := math.count_digits_of_base(n, base)
|
||||
str := strconv.append_int(buf[:], n, base)
|
||||
if !testing.expectf(t,
|
||||
len(str) == count,
|
||||
"decimal %i in base-%i digit count is %i, does not match length %i of %q",
|
||||
n, base, count, len(str), str) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_run_test(t, 2)
|
||||
_run_test(t, 3)
|
||||
_run_test(t, 4)
|
||||
_run_test(t, 5)
|
||||
_run_test(t, 6)
|
||||
_run_test(t, 7)
|
||||
_run_test(t, 8)
|
||||
_run_test(t, 9)
|
||||
_run_test(t, 10)
|
||||
_run_test(t, 11)
|
||||
_run_test(t, 12)
|
||||
_run_test(t, 13)
|
||||
_run_test(t, 14)
|
||||
_run_test(t, 15)
|
||||
_run_test(t, 16)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user