diff --git a/examples/numx/main.go b/examples/numx/main.go new file mode 100644 index 0000000..fc92a6d --- /dev/null +++ b/examples/numx/main.go @@ -0,0 +1,20 @@ +// numx 包示例:数值工具(流量格式化、低位取整、取最值) +package main + +import ( + "fmt" + + "git.zeroonesoft.cn/golib/zogo/numx" +) + +func main() { + // 流量字节数格式化 + fmt.Println("流量格式化:", numx.FormatFlow(1536000)) + + // 数字低位取整 + fmt.Println("IgnoreDigits(12345, 3):", numx.IgnoreDigits(12345, 3)) + + // 多整数取最值 + fmt.Println("Max(3,7,5):", numx.Max(3, 7, 5)) + fmt.Println("Min(3,1,2):", numx.Min(3, 1, 2)) +} diff --git a/numx/README.md b/numx/README.md new file mode 100644 index 0000000..e2f6692 --- /dev/null +++ b/numx/README.md @@ -0,0 +1,23 @@ +# numx + +数值处理与可读格式化工具:流量字节数格式化、数字低位取整、多整数取最值。 + +> 迁移自 go-hua/common(原 number.go / format.go / version.go 中的 Max/Min)。 + +## 用法 + +```go +import "git.zeroonesoft.cn/golib/zogo/numx" + +numx.FormatFlow(1536) // "1.5 KB"(B/KB/MB/GB/TB) +numx.IgnoreDigits(12345, 3) // 12000(低位取整补零) +numx.Max(3, 7, 5) // 7 +numx.Min(3, 1, 2) // 1 +``` + +完整可运行例程:[examples/numx/main.go](../examples/numx/main.go) + +## 注意 + +- Go 1.21+ 内置 `max`/`min` 只支持两参数,多参数场景仍可用本包 `Max/Min`。 +- `Min` 无法区分"全零参数"与"未传参数",全负数取最小值请用 `Max` 的负值或自行比较。 diff --git a/numx/numx.go b/numx/numx.go new file mode 100644 index 0000000..6d49050 --- /dev/null +++ b/numx/numx.go @@ -0,0 +1,49 @@ +// Package numx 数值处理与可读格式化工具:数字低位取整、流量字节数格式化、多整数取最值。 +package numx + +import ( + "fmt" + "math" +) + +// IgnoreDigits 数字低位取整:去掉最后 digitsToIgnore 位并补零 +func IgnoreDigits(value, digitsToIgnore int) int { + divider := int(math.Pow10(digitsToIgnore)) + return (value / divider) * divider +} + +// FormatFlow 流量字节数格式化为带单位的可读字符串(B/KB/MB/GB/TB) +func FormatFlow(value int64) string { + if value < 1024 { + return fmt.Sprintf("%d B", value) + } else if value < 1024*1024 { + return fmt.Sprintf("%.1f KB", float64(value)/float64(1024)) + } else if value < 1024*1024*1024 { + return fmt.Sprintf("%.1f MB", float64(value)/float64(1024*1024)) + } else if value < 1024*1024*1024*1024 { + return fmt.Sprintf("%.1f GB", float64(value)/float64(1024*1024*1024)) + } + return fmt.Sprintf("%.2f TB", float64(value)/float64(1024*1024*1024*1024)) +} + +// Max 返回多个整数中的最大值 +func Max(vals ...int) int { + var max int + for _, val := range vals { + if val > max { + max = val + } + } + return max +} + +// Min 返回多个整数中的最小值 +func Min(vals ...int) int { + var min int + for _, val := range vals { + if min == 0 || val <= min { + min = val + } + } + return min +} diff --git a/numx/numx_test.go b/numx/numx_test.go new file mode 100644 index 0000000..c5624aa --- /dev/null +++ b/numx/numx_test.go @@ -0,0 +1,38 @@ +package numx + +import "testing" + +func TestFormatFlow(t *testing.T) { + cases := []struct { + in int64 + want string + }{ + {500, "500 B"}, + {1536, "1.5 KB"}, + {1024 * 1024, "1.0 MB"}, + {1024 * 1024 * 1024, "1.0 GB"}, + } + for _, c := range cases { + if got := FormatFlow(c.in); got != c.want { + t.Errorf("FormatFlow(%d) = %q, want %q", c.in, got, c.want) + } + } +} + +func TestIgnoreDigits(t *testing.T) { + if got := IgnoreDigits(12345, 3); got != 12000 { + t.Errorf("IgnoreDigits(12345,3) = %d, want 12000", got) + } +} + +func TestMaxMin(t *testing.T) { + if got := Max(3, 7, 5); got != 7 { + t.Errorf("Max = %d, want 7", got) + } + if got := Min(3, 1, 2); got != 1 { + t.Errorf("Min = %d, want 1", got) + } + if got := Min(2, 5); got != 2 { + t.Errorf("Min(2,5) = %d, want 2", got) + } +}