properly handle formatting, preventing rounding errors for the case of 2.1 -> 2.09
Some checks failed
release / docker (push) Has been cancelled
Some checks failed
release / docker (push) Has been cancelled
This commit is contained in:
parent
38ab1ecdd1
commit
4c80606b56
@ -7,6 +7,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||||
)
|
)
|
||||||
@ -21,25 +22,34 @@ type TransactionData struct {
|
|||||||
ActiveAddress string
|
ActiveAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
// TruncateDecimalString safely truncates the input amount to the specified decimal places
|
// TruncateDecimalString safely truncates (not rounds) a number string to the specified decimal places
|
||||||
func TruncateDecimalString(input string, decimalPlaces int) (string, error) {
|
func TruncateDecimalString(input string, decimalPlaces int) (string, error) {
|
||||||
num, ok := new(big.Float).SetString(input)
|
if _, err := strconv.ParseFloat(input, 64); err != nil {
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("invalid input")
|
return "", fmt.Errorf("invalid input")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply by 10^decimalPlaces
|
// Split input into integer and fractional parts
|
||||||
scale := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimalPlaces)), nil))
|
parts := strings.SplitN(input, ".", 2)
|
||||||
scaled := new(big.Float).Mul(num, scale)
|
intPart := parts[0]
|
||||||
|
var fracPart string
|
||||||
|
|
||||||
// Truncate by converting to int (chops off decimals)
|
if len(parts) == 2 {
|
||||||
intPart, _ := scaled.Int(nil)
|
fracPart = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
// Divide back to get truncated float
|
// Truncate or pad fractional part
|
||||||
truncated := new(big.Float).Quo(new(big.Float).SetInt(intPart), scale)
|
if len(fracPart) > decimalPlaces {
|
||||||
|
fracPart = fracPart[:decimalPlaces]
|
||||||
|
} else {
|
||||||
|
fracPart = fracPart + strings.Repeat("0", decimalPlaces-len(fracPart))
|
||||||
|
}
|
||||||
|
|
||||||
// Format with fixed decimals
|
// Handle zero decimal places
|
||||||
return truncated.Text('f', decimalPlaces), nil
|
if decimalPlaces == 0 {
|
||||||
|
return intPart, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s.%s", intPart, fracPart), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAndScaleAmount(storedAmount, activeDecimal string) (string, error) {
|
func ParseAndScaleAmount(storedAmount, activeDecimal string) (string, error) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user