Data Unit Converter — Go source
Convert between digital data units - B, KB/KiB, MB/MiB, GB/GiB, TB/TiB. Switch between decimal (1000) and binary (1024) bases, runs entirely in your browser.
This is the Go implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Package dataunits is the Go twin of CosmoDev's src/lib/dataUnits.ts (dual
// source: the web lib is TypeScript, the CLI lib is Go — kept in lock-step).
// Pure + deterministic, never panics. The table-driven tests in
// data-unit-converter_test.go share vectors with src/lib/dataUnits.test.ts so
// the two implementations are held to the same contract.
//
// The algorithm mirrors the TS lib exactly: each unit has a power-of-base rank
// (B=0, each prefix step +1); bytes = value × base^fromExp, result =
// bytes / base^toExp. Non-finite values, unknown units, or an invalid base yield
// NaN — exactly as the TS lib's guards do, never throwing.
package dataunits
import "math"
// Units available under each base, ordered from smallest (B) to largest. Mirrors
// the UNITS record in src/lib/dataUnits.ts.
var Units = map[int][]string{
1000: {"B", "KB", "MB", "GB", "TB"},
1024: {"B", "KiB", "MiB", "GiB", "TiB"},
}
// Valid conversion bases (decimal 1000, binary 1024).
const (
BaseDecimal = 1000
BaseBinary = 1024
)
// exponent is the power-of-base rank for each unit: B is rank 0, each prefix
// steps by 1. Mirrors the EXPONENT record in src/lib/dataUnits.ts (unexported).
var exponent = map[string]int{
"B": 0,
"KB": 1, "MB": 2, "GB": 3, "TB": 4,
"KiB": 1, "MiB": 2, "GiB": 3, "TiB": 4,
}
// pow returns base raised to the non-negative integer power exp. Implemented as
// repeated multiplication (exponents here are 0–4) so the result is exact for
// integer bases — base^4 for 1000 is exactly 1e12, for 1024 exactly 2^40 — with
// no floating-point rounding, matching the integer-arithmetic intent of the TS
// lib's `base ** exp`.
func pow(base, exp int) float64 {
r := 1.0
for i := 0; i < exp; i++ {
r *= float64(base)
}
return r
}
// ConvertData converts a value between two digital-data units under the given
// base. It is the Go twin of convertData() in src/lib/dataUnits.ts and must agree
// with it on every shared vector.
//
// bytes = value × base^exp(fromUnit); result = bytes / base^exp(toUnit).
// Returns NaN for non-finite input, unknown units, or an invalid base — never
// panics.
func ConvertData(value float64, fromUnit, toUnit string, base int) float64 {
if math.IsNaN(value) || math.IsInf(value, 0) {
return math.NaN()
}
if base != BaseDecimal && base != BaseBinary {
return math.NaN()
}
fromExp, okFrom := exponent[fromUnit]
toExp, okTo := exponent[toUnit]
if !okFrom || !okTo {
return math.NaN()
}
return (value * pow(base, fromExp)) / pow(base, toExp)
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →