format: use binary prefixes for HumanBytes file size formatting
Change HumanBytes to use binary prefixes (1024-based) instead of decimal (1000-based) for file size formatting. This fixes the rounding error where 3072 bytes was displayed as '3.1 KB' instead of '3 KB'. The decimal constants (KiloByte, MegaByte, etc.) are preserved for other uses like buffer sizes and memory capacity. Fixes #13405
This commit is contained in:
parent
18fdcc94e5
commit
524486b412
|
|
@ -8,32 +8,37 @@ import (
|
||||||
const (
|
const (
|
||||||
Byte = 1
|
Byte = 1
|
||||||
|
|
||||||
|
// Decimal prefixes (1000-based) - used for buffer sizes, memory capacity
|
||||||
KiloByte = Byte * 1000
|
KiloByte = Byte * 1000
|
||||||
MegaByte = KiloByte * 1000
|
MegaByte = KiloByte * 1000
|
||||||
GigaByte = MegaByte * 1000
|
GigaByte = MegaByte * 1000
|
||||||
TeraByte = GigaByte * 1000
|
TeraByte = GigaByte * 1000
|
||||||
|
|
||||||
|
// Binary prefixes (1024-based) - used for file sizes
|
||||||
KibiByte = Byte * 1024
|
KibiByte = Byte * 1024
|
||||||
MebiByte = KibiByte * 1024
|
MebiByte = KibiByte * 1024
|
||||||
GibiByte = MebiByte * 1024
|
GibiByte = MebiByte * 1024
|
||||||
|
TebiByte = GibiByte * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HumanBytes formats bytes using binary prefixes (1024-based) with short unit names.
|
||||||
|
// This follows the convention used by most file systems and tools for file sizes.
|
||||||
func HumanBytes(b int64) string {
|
func HumanBytes(b int64) string {
|
||||||
var value float64
|
var value float64
|
||||||
var unit string
|
var unit string
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case b >= TeraByte:
|
case b >= TebiByte:
|
||||||
value = float64(b) / TeraByte
|
value = float64(b) / TebiByte
|
||||||
unit = "TB"
|
unit = "TB"
|
||||||
case b >= GigaByte:
|
case b >= GibiByte:
|
||||||
value = float64(b) / GigaByte
|
value = float64(b) / GibiByte
|
||||||
unit = "GB"
|
unit = "GB"
|
||||||
case b >= MegaByte:
|
case b >= MebiByte:
|
||||||
value = float64(b) / MegaByte
|
value = float64(b) / MebiByte
|
||||||
unit = "MB"
|
unit = "MB"
|
||||||
case b >= KiloByte:
|
case b >= KibiByte:
|
||||||
value = float64(b) / KiloByte
|
value = float64(b) / KibiByte
|
||||||
unit = "KB"
|
unit = "KB"
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("%d B", b)
|
return fmt.Sprintf("%d B", b)
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,34 @@ func TestHumanBytes(t *testing.T) {
|
||||||
// Test bytes (B)
|
// Test bytes (B)
|
||||||
{0, "0 B"},
|
{0, "0 B"},
|
||||||
{1, "1 B"},
|
{1, "1 B"},
|
||||||
{999, "999 B"},
|
{1023, "1023 B"},
|
||||||
|
|
||||||
// Test kilobytes (KB)
|
// Test kilobytes (KB) - binary prefix (1024-based)
|
||||||
{1000, "1 KB"},
|
{1024, "1 KB"},
|
||||||
{1500, "1.5 KB"},
|
{1536, "1.5 KB"},
|
||||||
{999999, "999 KB"},
|
{3072, "3 KB"},
|
||||||
|
{4096, "4 KB"},
|
||||||
|
{10240, "10 KB"},
|
||||||
|
|
||||||
// Test megabytes (MB)
|
// Test megabytes (MB) - binary prefix (1024-based)
|
||||||
{1000000, "1 MB"},
|
{1048576, "1 MB"},
|
||||||
{1500000, "1.5 MB"},
|
{1572864, "1.5 MB"},
|
||||||
{999999999, "999 MB"},
|
{10485760, "10 MB"},
|
||||||
|
|
||||||
// Test gigabytes (GB)
|
// Test gigabytes (GB) - binary prefix (1024-based)
|
||||||
{1000000000, "1 GB"},
|
{1073741824, "1 GB"},
|
||||||
{1500000000, "1.5 GB"},
|
{1610612736, "1.5 GB"},
|
||||||
{999999999999, "999 GB"},
|
{10737418240, "10 GB"},
|
||||||
|
|
||||||
// Test terabytes (TB)
|
// Test terabytes (TB) - binary prefix (1024-based)
|
||||||
{1000000000000, "1 TB"},
|
{1099511627776, "1 TB"},
|
||||||
{1500000000000, "1.5 TB"},
|
{1649267441664, "1.5 TB"},
|
||||||
{1999999999999, "2.0 TB"},
|
{2199023255552, "2 TB"},
|
||||||
|
|
||||||
// Test fractional values
|
// Test fractional values
|
||||||
{1234, "1.2 KB"},
|
{1280, "1.2 KB"},
|
||||||
{1234567, "1.2 MB"},
|
{1310720, "1.2 MB"},
|
||||||
{1234567890, "1.2 GB"},
|
{1342177280, "1.2 GB"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue