package binancerecharge import ( "fmt" "math/big" "net/http" "strings" ) func parsePositiveDecimal(value string, field string) (*big.Rat, string, error) { normalized, err := normalizeDecimal(value) if err != nil { return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be a decimal number") } rat, ok := new(big.Rat).SetString(normalized) if !ok || rat.Sign() <= 0 { return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be greater than 0") } return rat, normalized, nil } func parseNonNegativeDecimal(value string, field string) (*big.Rat, string, error) { normalized, err := normalizeDecimal(value) if err != nil { return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be a decimal number") } rat, ok := new(big.Rat).SetString(normalized) if !ok || rat.Sign() < 0 { return nil, "", NewAppError(http.StatusBadRequest, "invalid_"+field, field+" must be greater than or equal to 0") } return rat, normalized, nil } func normalizeDecimal(value string) (string, error) { value = strings.TrimSpace(value) if value == "" { return "", fmt.Errorf("blank decimal") } rat, ok := new(big.Rat).SetString(value) if !ok { return "", fmt.Errorf("invalid decimal") } return trimDecimalZeros(rat.FloatString(8)), nil } func trimDecimalZeros(value string) string { value = strings.TrimSpace(value) if !strings.Contains(value, ".") { return value } value = strings.TrimRight(value, "0") value = strings.TrimRight(value, ".") if value == "" || value == "-0" { return "0" } return value } func decimalEqual(left string, right string) bool { leftRat, ok := new(big.Rat).SetString(strings.TrimSpace(left)) if !ok { return false } rightRat, ok := new(big.Rat).SetString(strings.TrimSpace(right)) if !ok { return false } return leftRat.Cmp(rightRat) == 0 } func calculateGold(amount *big.Rat, rate *big.Rat) (int64, error) { product := new(big.Rat).Mul(amount, rate) gold := new(big.Int).Quo(product.Num(), product.Denom()) if !gold.IsInt64() { return 0, NewAppError(http.StatusBadRequest, "gold_amount_too_large", "gold amount is too large") } return gold.Int64(), nil }