mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
fix: fix DecimalBytes and BinaryBytes issue #232
This commit is contained in:
@@ -6,6 +6,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
)
|
||||
|
||||
//
|
||||
@@ -91,32 +94,21 @@ func DecimalBytes(size float64, precision ...int) string {
|
||||
|
||||
size, unit := calculateByteSize(size, 1000.0, decimalByteUnits)
|
||||
|
||||
format := fmt.Sprintf("%%.%df", pointPosition)
|
||||
bytes := fmt.Sprintf(format, size)
|
||||
|
||||
for i := len(bytes); i > 0; i-- {
|
||||
s := bytes[i-1]
|
||||
if s != '0' && s != '.' {
|
||||
break
|
||||
}
|
||||
|
||||
bytes = bytes[:i-1]
|
||||
}
|
||||
|
||||
return bytes + unit
|
||||
return roundToToString(size, pointPosition) + unit
|
||||
}
|
||||
|
||||
// BinaryBytes returns a human-readable byte size under binary standard (base 1024)
|
||||
// The precision parameter specifies the number of digits after the decimal point, which defaults to 4.
|
||||
// Play: https://go.dev/play/p/G9oHHMCAZxP
|
||||
func BinaryBytes(size float64, precision ...int) string {
|
||||
p := 5
|
||||
pointPosition := 4
|
||||
if len(precision) > 0 {
|
||||
p = precision[0] + 1
|
||||
pointPosition = precision[0]
|
||||
}
|
||||
|
||||
size, unit := calculateByteSize(size, 1024.0, binaryByteUnits)
|
||||
|
||||
return fmt.Sprintf("%.*g%s", p, size, unit)
|
||||
return roundToToString(size, pointPosition) + unit
|
||||
}
|
||||
|
||||
func calculateByteSize(size float64, base float64, byteUnits []string) (float64, string) {
|
||||
@@ -129,6 +121,29 @@ func calculateByteSize(size float64, base float64, byteUnits []string) (float64,
|
||||
return size, byteUnits[i]
|
||||
}
|
||||
|
||||
func roundToToString(x float64, max ...int) string {
|
||||
pointPosition := 4
|
||||
if len(max) > 0 {
|
||||
pointPosition = max[0]
|
||||
}
|
||||
result := mathutil.RoundToString(x, pointPosition)
|
||||
|
||||
// 删除小数位结尾的0
|
||||
decimal := strings.TrimRight(strutil.After(result, "."), "0")
|
||||
if decimal == "" || pointPosition == 0 {
|
||||
// 没有小数位直接返回整数
|
||||
return strutil.Before(result, ".")
|
||||
}
|
||||
|
||||
// 小数位大于想要设置的位数,按需要截断
|
||||
if len(decimal) > pointPosition {
|
||||
return strutil.Before(result, ".") + "." + decimal[:pointPosition]
|
||||
}
|
||||
|
||||
// 小数位小于等于想要的位数,直接拼接返回
|
||||
return strutil.Before(result, ".") + "." + decimal
|
||||
}
|
||||
|
||||
// ParseDecimalBytes return the human readable bytes size string into the amount it represents(base 1000).
|
||||
// ParseDecimalBytes("42 MB") -> 42000000, nil
|
||||
// Play: https://go.dev/play/p/Am98ybWjvjj
|
||||
|
||||
@@ -25,6 +25,9 @@ func TestDecimalBytes(t *testing.T) {
|
||||
assert.Equal("401MB", DecimalBytes(401000000))
|
||||
assert.Equal("401MB", DecimalBytes(401000000, 0))
|
||||
assert.Equal("4MB", DecimalBytes(4010000, 0))
|
||||
|
||||
assert.Equal("4MB", DecimalBytes(4000000, 0))
|
||||
assert.Equal("4MB", DecimalBytes(4000000, 1))
|
||||
}
|
||||
|
||||
func TestBinaryBytes(t *testing.T) {
|
||||
@@ -36,6 +39,10 @@ func TestBinaryBytes(t *testing.T) {
|
||||
assert.Equal("1MiB", BinaryBytes(1024*1024))
|
||||
assert.Equal("1.1774MiB", BinaryBytes(1234567))
|
||||
assert.Equal("1.18MiB", BinaryBytes(1234567, 2))
|
||||
|
||||
assert.Equal("10KiB", BinaryBytes(10240, 0))
|
||||
assert.Equal("10KiB", BinaryBytes(10240, 1))
|
||||
assert.Equal("10KiB", BinaryBytes(10240, 2))
|
||||
}
|
||||
|
||||
func TestParseDecimalBytes(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user