func ratmod(x, y *big.Rat) *big.Rat { if x.IsInt() && y.IsInt() { return new(big.Rat).SetInt(new(big.Int).Mod(x.Num(), y.Num())) } panic("operation not permitted") }
// coinUnits converts a siacoin amount to base units. func coinUnits(amount string) (string, error) { units := []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"} for i, unit := range units { if strings.HasSuffix(amount, unit) { // scan into big.Rat r, ok := new(big.Rat).SetString(strings.TrimSuffix(amount, unit)) if !ok { return "", errors.New("malformed amount") } // convert units exp := 24 + 3*(int64(i)-4) mag := new(big.Int).Exp(big.NewInt(10), big.NewInt(exp), nil) r.Mul(r, new(big.Rat).SetInt(mag)) // r must be an integer at this point if !r.IsInt() { return "", errors.New("non-integer number of hastings") } return r.RatString(), nil } } // check for hastings separately if strings.HasSuffix(amount, "H") { return strings.TrimSuffix(amount, "H"), nil } return "", errors.New("amount is missing units; run 'wallet --help' for a list of units") }
// parseFilesize converts strings of form 10GB to a size in bytes. Fractional // sizes are truncated at the byte size. func parseFilesize(strSize string) (string, error) { units := []struct { suffix string multiplier int64 }{ {"kb", 1e3}, {"mb", 1e6}, {"gb", 1e9}, {"tb", 1e12}, {"kib", 1 << 10}, {"mib", 1 << 20}, {"gib", 1 << 30}, {"tib", 1 << 40}, {"b", 1}, // must be after others else it'll match on them all {"", 1}, // no suffix is still a valid suffix } strSize = strings.ToLower(strSize) for _, unit := range units { if strings.HasSuffix(strSize, unit.suffix) { r, ok := new(big.Rat).SetString(strings.TrimSuffix(strSize, unit.suffix)) if !ok { return "", errUnableToParseSize } r.Mul(r, new(big.Rat).SetInt(big.NewInt(unit.multiplier))) if !r.IsInt() { f, _ := r.Float64() return fmt.Sprintf("%d", int64(f)), nil } return r.RatString(), nil } } return "", errUnableToParseSize }
// Returns the parsed duration in nanoseconds, support 'u', 's', 'm', // 'h', 'd', 'W', 'M', and 'Y' suffixes. func ParseTimeDuration(value string) (int64, error) { var constant time.Duration prefixSize := 1 switch value[len(value)-1] { case 'u': constant = time.Microsecond case 's': constant = time.Second case 'm': constant = time.Minute case 'h': constant = time.Hour case 'd': constant = 24 * time.Hour case 'w', 'W': constant = Week case 'M': constant = Month case 'y', 'Y': constant = Year default: prefixSize = 0 } if value[len(value)-2:] == "ms" { constant = time.Millisecond prefixSize = 2 } t := big.Rat{} timeString := value if prefixSize > 0 { timeString = value[:len(value)-prefixSize] } _, err := fmt.Sscan(timeString, &t) if err != nil { return 0, err } if prefixSize > 0 { c := big.Rat{} c.SetFrac64(int64(constant), 1) t.Mul(&t, &c) } if t.IsInt() { return t.Num().Int64(), nil } f, _ := t.Float64() return int64(f), nil }
func NewRational(r *big.Rat) Rational { if !r.IsInt() || r.Cmp(min) < 0 || r.Cmp(max) > 0 { return Rational{r} } n := r.Num().Int64() i := n + 256 p := rat[i] if p.v == nil { p = Rational{r} rat[i] = p } return p }
func parseResourceCPU(flags *pflag.FlagSet, resources *api.Resources, name string) error { cpu, err := flags.GetString(name) if err != nil { return err } nanoCPUs, ok := new(big.Rat).SetString(cpu) if !ok { return fmt.Errorf("invalid cpu: %s", cpu) } cpuRat := new(big.Rat).Mul(nanoCPUs, big.NewRat(1e9, 1)) if !cpuRat.IsInt() { return fmt.Errorf("CPU value cannot have more than 9 decimal places: %s", cpu) } resources.NanoCPUs = cpuRat.Num().Int64() return nil }
// Returns the parsed duration in nanoseconds, support 'u', 's', 'm', // 'h', 'd' and 'w' suffixes. func ParseTimeDuration(value string) (int64, error) { var constant time.Duration hasPrefix := true switch value[len(value)-1] { case 'u': constant = time.Microsecond case 's': constant = time.Second case 'm': constant = time.Minute case 'h': constant = time.Hour case 'd': constant = 24 * time.Hour case 'w': constant = 7 * 24 * time.Hour case 'y': constant = 365 * 24 * time.Hour default: hasPrefix = false } t := big.Rat{} timeString := value if hasPrefix { timeString = value[:len(value)-1] } _, err := fmt.Sscan(timeString, &t) if err != nil { return 0, err } if hasPrefix { c := big.Rat{} c.SetFrac64(int64(constant), 1) t.Mul(&t, &c) } if t.IsInt() { return t.Num().Int64(), nil } f, _ := t.Float64() return int64(f), nil }
func NewRational(r *big.Rat) *Rational { if !r.IsInt() || r.Cmp(min) < 0 || r.Cmp(max) > 0 { return (*Rational)(r) } n := r.Num().Int64() i := n + 256 ratl.RLock() p := rat[i] ratl.RUnlock() if p == nil { p = (*Rational)(r) ratl.Lock() rat[i] = p ratl.Unlock() } return p }
// normalizeRatConst returns the smallest constant representation // for the specific value of x; either an int64, *big.Int value, // or *big.Rat value. // func normalizeRatConst(x *big.Rat) interface{} { if x.IsInt() { return normalizeIntConst(x.Num()) } return x }
func normFloat(x *big.Rat) Value { if x.IsInt() { return normInt(x.Num()) } return floatVal{x} }
func num(x *big.Rat) string { if x.IsInt() { return x.Num().String() } return x.String() }