Skip to content

Instantly share code, notes, and snippets.

@anikitenko
Created October 11, 2017 07:41
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • 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))
}
@anikitenko
Copy link
Author

@qxxt
Copy link

qxxt commented Jan 14, 2022

Or simpler:
byte to kb = float(n)/(1<<10)
byte to mb = float(n)/(1<<20)
byte to gb = float(n)/(1<<30)
....

@anikitenko
Copy link
Author

@qxxt can you please provide more information about your solution?

@qxxt
Copy link

qxxt commented Jan 24, 2022

(1<<10) is 1024. It is a byte shift operation. 1024 byte is equal to 1 kb.

(1<<20) is also a byte shift operation and is equal to 1024*1024. It's a total byte of 1mb. Byte unit are a base2 number.

1gb is 1mb*1mb, and so on...

@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