Skip to content

Instantly share code, notes, and snippets.

@anikitenko
Created October 11, 2017 07:41
Show Gist options
  • Save anikitenko/b41206a49727b83a530142c76b1cb82d to your computer and use it in GitHub Desktop.
Save anikitenko/b41206a49727b83a530142c76b1cb82d to your computer and use it in GitHub Desktop.
[Golang] Convert size in bytes to Bytes, Kilobytes, Megabytes, GB and TB
package main
import (
"fmt"
"math"
"strconv"
)
var (
sizeInMB float64 = 999 // This is in megabytes
suffixes [5]string
)
func Round(val float64, roundOn float64, places int ) (newVal float64) {
var round float64
pow := math.Pow(10, float64(places))
digit := pow * val
_, div := math.Modf(digit)
if div >= roundOn {
round = math.Ceil(digit)
} else {
round = math.Floor(digit)
}
newVal = round / pow
return
}
func main() {
size := sizeInMB * 1024 * 1024 // This is in bytes
suffixes[0] = "B"
suffixes[1] = "KB"
suffixes[2] = "MB"
suffixes[3] = "GB"
suffixes[4] = "TB"
base := math.Log(size)/math.Log(1024)
getSize := Round(math.Pow(1024, base - math.Floor(base)), .5, 2)
getSuffix := suffixes[int(math.Floor(base))]
fmt.Println(strconv.FormatFloat(getSize, 'f', -1, 64)+" "+string(getSuffix))
}
@qxxt
Copy link

qxxt commented Jan 24, 2022

@anikitenko
And since binary is base 2.
1<<10 is equal to 2^10.
1<<20 = 2^20.
....

@caseyduquettesc
Copy link

const (
    _ = 1 << (10 * iota)
    KiB
    MiB
    GiB
    TiB
)

KiB = 1_024
MiB = 1_048_576
GiB = 1_073_741_824
TiB = 1_099_511_627_776

@thisisankit27
Copy link

const (
_ = iota //ignore first value by assigning to blank identifier
KB = 1 << (10 * iota)
MB
GB
TB
PB
EB
ZB
YB
)

@anikitenko
Copy link
Author

anikitenko commented May 3, 2022

@thisisankit27 thank you but how will these consts help me to determine for example 618761333 bytes are exactly KB, MB, GB? The reason I'm asking is that my mathematical method allows to determine index in array but what about const?

@maxmcd
Copy link

maxmcd commented Feb 11, 2023

Simpler:

func prettyByteSize(b int) string {
	bf := float64(b)
	for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
		if math.Abs(bf) < 1024.0 {
			return fmt.Sprintf("%3.1f%sB", bf, unit)
		}
		bf /= 1024.0
	}
	return fmt.Sprintf("%.1fYiB", bf)
}

Converted from here: https://stackoverflow.com/a/1094933/1333724

@fresonn
Copy link

fresonn commented Nov 6, 2023

@maxmcd thanks 😇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment