Documentation
¶
Overview ¶
Package decint provides utility functions to parse and represent decimal values as fixed-point integers with a defined precision.
This package solves the common problem of safely handling small monetary and fixed-precision decimal values without using floating-point arithmetic for storage or comparison.
Decint is designed for values with at most six decimal places, and it stores those values as integers (scaled by 1e6) to preserve deterministic behavior in comparisons, serialization, and transport.
Top features:
- bidirectional conversion between float64/string and scaled int64 or uint64 - fixed six-decimal output formatting for stable text representation - explicit parse errors for invalid numeric strings - published safe range constants (MaxInt and MaxFloat) for boundary checks - unsigned conversion helpers that clamp non-positive values to zero
Implementation note:
- float-to-integer conversion scales by 1e6 and rounds to the nearest integer (half away from zero), so extra fractional digits beyond the supported precision are rounded rather than truncated.
Key benefits:
- deterministic decimal handling for currency, rates, and small amounts - exact six-decimal representation for every value within the safe range
Safe range:
- Values are safe up to MaxFloat = 2^33 = 8_589_934_592 with six exact decimal places. This is the largest magnitude at which a float64 still resolves a 1e-6 step (its ULP stays below 1e-6); beyond it the sixth decimal digit is no longer representable, so it is intentionally excluded from the safe range rather than silently rounded.
Index ¶
- Constants
- Variables
- func FloatToInt(v float64) int64
- func FloatToUint(v float64) uint64
- func IntToFloat(v int64) float64
- func IntToString(v int64) string
- func StringToInt(s string) (int64, error)
- func StringToUint(s string) (uint64, error)
- func UintToFloat(v uint64) float64
- func UintToString(v uint64) string
Examples ¶
Constants ¶
const ( // MaxInt is the maximum scaled integer that preserves six exact decimals // (2^33 * 1e6). It is below 2^53, so it is still an exact float64. MaxInt = 8_589_934_592_000_000 // MaxFloat is the maximum value that preserves six exact decimals in a // float64 (2^33). Above it the float64 ULP exceeds 1e-6 and the sixth // decimal digit can no longer be represented. MaxFloat = 8_589_934_592 )
Variables ¶
var ( // ErrInvalidNumber indicates the input string is not a valid finite number. ErrInvalidNumber = errors.New("invalid decimal number") // ErrOutOfRange indicates the value is outside the safe range. ErrOutOfRange = errors.New("value out of safe range") )
Functions ¶
func FloatToInt ¶
FloatToInt converts a decimal float into the scaled int64 fixed-point form.
The value is multiplied by 1e6 and rounded to the nearest integer (half away from zero), so exact decimal inputs whose float64 form is one ULP off (e.g. 8.2) still map to their exact scaled value.
Non-finite and out-of-range inputs are clamped (the signature is preserved): NaN yields 0, +Inf or values above MaxFloat yield MaxInt, and -Inf or values below -MaxFloat yield -MaxInt.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.FloatToInt(123.456)
fmt.Println(v)
}
Output: 123456000
func FloatToUint ¶
FloatToUint converts a decimal float into the scaled uint64 fixed-point form.
The value is multiplied by 1e6 and rounded to the nearest integer (half away from zero), so exact decimal inputs whose float64 form is one ULP off (e.g. 8.2) still map to their exact scaled value.
Values less than or equal to zero are clamped to 0, making this helper safe for unsigned amount domains.
Non-finite and out-of-range inputs are clamped (the signature is preserved): NaN and values less than or equal to zero (including -Inf) yield 0, while +Inf or values above MaxFloat yield MaxInt.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.FloatToUint(123.456)
fmt.Println(v)
}
Output: 123456000
func IntToFloat ¶
IntToFloat converts a scaled int64 fixed-point value back to float64.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.IntToFloat(123456)
fmt.Println(v)
}
Output: 0.123456
func IntToString ¶
IntToString formats a scaled int64 value as a six-decimal string.
The value is formatted directly from the integer, so the output is exact for every int64 (including values outside the safe range) and independent of float64 precision.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.IntToString(123456)
fmt.Println(v)
}
Output: 0.123456
func StringToInt ¶
StringToInt parses a decimal string and returns its scaled int64 form.
This is useful when ingesting textual values from config, APIs, or storage while preserving the package's fixed-point representation.
Unlike FloatToInt, which clamps non-finite and out-of-range values, this function returns an error wrapping ErrInvalidNumber when the string cannot be parsed or is NaN or infinite, and ErrOutOfRange when the value is outside the safe range [-MaxFloat, MaxFloat].
Example ¶
package main
import (
"fmt"
"log"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v, err := decint.StringToInt("123456")
if err != nil {
log.Fatal(err)
}
fmt.Println(v)
}
Output: 123456000000
func StringToUint ¶
StringToUint parses a decimal string and returns its scaled uint64 form.
The rules mirror the unsigned domain:
- a string that cannot be parsed, or that is NaN or infinite (either sign), returns an error wrapping ErrInvalidNumber;
- a finite value less than or equal to zero is clamped to 0 (no error);
- a finite value above MaxFloat returns an error wrapping ErrOutOfRange.
Example ¶
package main
import (
"fmt"
"log"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v, err := decint.StringToUint("123.456")
if err != nil {
log.Fatal(err)
}
fmt.Println(v)
}
Output: 123456000
func UintToFloat ¶
UintToFloat converts a scaled uint64 fixed-point value back to float64.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.UintToFloat(123456)
fmt.Println(v)
}
Output: 0.123456
func UintToString ¶
UintToString formats a scaled uint64 value as a six-decimal string.
The value is formatted directly from the integer, so the output is exact for every uint64 (including values outside the safe range) and independent of float64 precision.
Example ¶
package main
import (
"fmt"
"github.com/tecnickcom/nurago/pkg/decint"
)
func main() {
v := decint.UintToString(123456)
fmt.Println(v)
}
Output: 0.123456
Types ¶
This section is empty.