1
0
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:
dudaodong
2024-08-19 11:36:49 +08:00
parent c0b200f846
commit bc260277bc
2 changed files with 38 additions and 16 deletions

View File

@@ -6,6 +6,9 @@ import (
"strconv" "strconv"
"strings" "strings"
"unicode" "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) size, unit := calculateByteSize(size, 1000.0, decimalByteUnits)
format := fmt.Sprintf("%%.%df", pointPosition) return roundToToString(size, pointPosition) + unit
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
} }
// BinaryBytes returns a human-readable byte size under binary standard (base 1024) // 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. // The precision parameter specifies the number of digits after the decimal point, which defaults to 4.
// Play: https://go.dev/play/p/G9oHHMCAZxP // Play: https://go.dev/play/p/G9oHHMCAZxP
func BinaryBytes(size float64, precision ...int) string { func BinaryBytes(size float64, precision ...int) string {
p := 5 pointPosition := 4
if len(precision) > 0 { if len(precision) > 0 {
p = precision[0] + 1 pointPosition = precision[0]
} }
size, unit := calculateByteSize(size, 1024.0, binaryByteUnits) 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) { 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] 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 return the human readable bytes size string into the amount it represents(base 1000).
// ParseDecimalBytes("42 MB") -> 42000000, nil // ParseDecimalBytes("42 MB") -> 42000000, nil
// Play: https://go.dev/play/p/Am98ybWjvjj // Play: https://go.dev/play/p/Am98ybWjvjj

View File

@@ -25,6 +25,9 @@ func TestDecimalBytes(t *testing.T) {
assert.Equal("401MB", DecimalBytes(401000000)) assert.Equal("401MB", DecimalBytes(401000000))
assert.Equal("401MB", DecimalBytes(401000000, 0)) assert.Equal("401MB", DecimalBytes(401000000, 0))
assert.Equal("4MB", DecimalBytes(4010000, 0)) assert.Equal("4MB", DecimalBytes(4010000, 0))
assert.Equal("4MB", DecimalBytes(4000000, 0))
assert.Equal("4MB", DecimalBytes(4000000, 1))
} }
func TestBinaryBytes(t *testing.T) { func TestBinaryBytes(t *testing.T) {
@@ -36,6 +39,10 @@ func TestBinaryBytes(t *testing.T) {
assert.Equal("1MiB", BinaryBytes(1024*1024)) assert.Equal("1MiB", BinaryBytes(1024*1024))
assert.Equal("1.1774MiB", BinaryBytes(1234567)) assert.Equal("1.1774MiB", BinaryBytes(1234567))
assert.Equal("1.18MiB", BinaryBytes(1234567, 2)) 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) { func TestParseDecimalBytes(t *testing.T) {