fix(strutil): return zero digit instead of empty string in base conversion

BaseConvIntByTpl returned an empty string for the value zero because its
loop condition (dec > 0) was never entered. This affected BaseConv,
Base10Conv and BaseConvInt for bases above 62, and was inconsistent with
BaseConvInt for smaller bases which correctly returned "0" via strconv.

Emit the zero digit of the target base for a zero input and guard against
an empty template.
This commit is contained in:
dualfroz committed 2026-09-04 09:00:39 +02:00
1 parent 17b49be136
commit d6c91f3cdd
3 files changed
+99

No files matched your search

+10
View File
@@ -100,6 +100,16 @@ func BaseConvIntByTpl(dec uint64, toBase string) string {
// convert to new base
var res string
toLen := uint64(len(toBase))
if toLen == 0 {
return res
}
// zero maps to the zero digit of the target base, otherwise the loop below
// would produce an empty string for a valid input.
if dec == 0 {
return string(toBase[0])
}
for dec > 0 {
res = string(toBase[dec%toLen]) + res
dec /= toLen
+15
View File
@@ -7,6 +7,21 @@ import (
"github.com/gookit/goutil/x/assert"
)
func TestBaseConv_zero(t *testing.T) {
// Zero must convert to the zero digit of the target base, not an empty
// string. This also keeps BaseConvInt consistent across all bases: the
// strconv-backed path already returns "0" for small bases.
assert.Eq(t, "0", strutil.BaseConv("0", 10, 16))
assert.Eq(t, "0", strutil.BaseConv("0", 16, 10))
assert.Eq(t, "0", strutil.Base10Conv("0", 62))
assert.Eq(t, "0", strutil.BaseConvInt(0, 16))
assert.Eq(t, "0", strutil.BaseConvInt(0, 62))
assert.Eq(t, "0", strutil.BaseConvInt(0, 64))
assert.Eq(t, "0", strutil.BaseConvIntByTpl(0, strutil.Base64Chars))
}
func TestBaseConv(t *testing.T) {
tests := []struct {
give string