func sqrt(n *big.Int) *big.Int { a := new(big.Int) for b := new(big.Int).Set(n); ; { a.Set(b) b.Rsh(b.Add(b.Quo(n, a), a), 1) if b.Cmp(a) >= 0 { return a } } return a.SetInt64(0) }
// mul multiplies the input amount by the input price func mul(amount int64, pricen int64, priced int64) int64 { var r, n, d big.Int r.SetInt64(amount) n.SetInt64(pricen) d.SetInt64(priced) r.Mul(&r, &n) r.Quo(&r, &d) return r.Int64() }
// Int64 returns the numeric value of this literal truncated to fit // a signed 64-bit integer. // func (l *Literal) Int64() int64 { switch x := l.Value.(type) { case int64: return x case *big.Int: return x.Int64() case *big.Rat: var q big.Int return q.Quo(x.Num(), x.Denom()).Int64() // truncate } panic(fmt.Sprintf("unexpected literal value: %T", l.Value)) }
// Int64 returns the numeric value of this literal truncated to fit // a signed 64-bit integer. // func (l *Literal) Int64() int64 { switch x := l.Value.(type) { case int64: return x case *big.Int: return x.Int64() case *big.Rat: // TODO(adonovan): fix: is this the right rounding mode? var q big.Int return q.Quo(x.Num(), x.Denom()).Int64() } panic(fmt.Sprintf("unexpected literal value: %T", l.Value)) }
func binaryIntOp(x *big.Int, op token.Token, y *big.Int) interface{} { var z big.Int switch op { case token.ADD: return z.Add(x, y) case token.SUB: return z.Sub(x, y) case token.MUL: return z.Mul(x, y) case token.QUO: return z.Quo(x, y) case token.REM: return z.Rem(x, y) case token.AND: return z.And(x, y) case token.OR: return z.Or(x, y) case token.XOR: return z.Xor(x, y) case token.AND_NOT: return z.AndNot(x, y) case token.SHL: // The shift length must be uint, or untyped int and // convertible to uint. // TODO 32/64bit if y.BitLen() > 32 { panic("Excessive shift length") } return z.Lsh(x, uint(y.Int64())) case token.SHR: if y.BitLen() > 32 { panic("Excessive shift length") } return z.Rsh(x, uint(y.Int64())) case token.EQL: return x.Cmp(y) == 0 case token.NEQ: return x.Cmp(y) != 0 case token.LSS: return x.Cmp(y) < 0 case token.LEQ: return x.Cmp(y) <= 0 case token.GTR: return x.Cmp(y) > 0 case token.GEQ: return x.Cmp(y) >= 0 } panic("unreachable") }
// eExponent returns the exponent to use to display i in 1.23e+04 format. func eExponent(x *big.Int) int { if x.Sign() < 0 { x.Neg(x) } e := 0 for x.Cmp(bigIntBillion) >= 0 { e += 9 x.Quo(x, bigIntBillion) } for x.Cmp(bigIntTen) >= 0 { e++ x.Quo(x, bigIntTen) } return e }
func moBachShallit58(a, n *big.Int, pf []pExp) *big.Int { n1 := new(big.Int).Sub(n, one) var x, y, o1, g big.Int mo := big.NewInt(1) for _, pe := range pf { y.Quo(n1, y.Exp(pe.prime, big.NewInt(pe.exp), nil)) var o int64 for x.Exp(a, &y, n); x.Cmp(one) > 0; o++ { x.Exp(&x, pe.prime, n) } o1.Exp(pe.prime, o1.SetInt64(o), nil) mo.Mul(mo, o1.Quo(&o1, g.GCD(nil, nil, mo, &o1))) } return mo }
func main() { ln2, _ := new(big.Rat).SetString("0.6931471805599453094172") h := big.NewRat(1, 2) h.Quo(h, ln2) var f big.Rat var w big.Int for i := int64(1); i <= 17; i++ { h.Quo(h.Mul(h, f.SetInt64(i)), ln2) w.Quo(h.Num(), h.Denom()) f.Sub(h, f.SetInt(&w)) y, _ := f.Float64() d := fmt.Sprintf("%.3f", y) fmt.Printf("n: %2d h: %18d%s Nearly integer: %t\n", i, &w, d[1:], d[2] == '0' || d[2] == '9') } }
// Uint64 returns the numeric value of this literal truncated to fit // an unsigned 64-bit integer. // func (l *Literal) Uint64() uint64 { switch x := l.Value.(type) { case int64: if x < 0 { return 0 } return uint64(x) case *big.Int: return x.Uint64() case *big.Rat: // TODO(adonovan): fix: is this right? var q big.Int return q.Quo(x.Num(), x.Denom()).Uint64() } panic(fmt.Sprintf("unexpected literal value: %T", l.Value)) }
func prime_divide(n *big.Int) []*big.Int { r := make([]*big.Int, 0, 10) a := big.NewInt(2) for a.Cmp(n) == -1 || a.Cmp(n) == 0 { t := big.NewInt(0) t.Mod(n, a) if t.Cmp(big.NewInt(0)) == 0 { r = append(r, a) a = big.NewInt(a.Int64()) n.Quo(n, a) } else { a.Add(a, big.NewInt(1)) } } return r }
// rescale returns a rescaled version of the decimal. Returned // decimal may be less precise if the given exponent is bigger // than the initial exponent of the Decimal. // NOTE: this will truncate, NOT round // // Example: // // d := New(12345, -4) // d2 := d.rescale(-1) // d3 := d2.rescale(-4) // println(d1) // println(d2) // println(d3) // // Output: // // 1.2345 // 1.2 // 1.2000 // func (d Decimal) rescale(exp int32) Decimal { d.ensureInitialized() // NOTE(vadim): must convert exps to float64 before - to prevent overflow diff := math.Abs(float64(exp) - float64(d.exp)) value := new(big.Int).Set(d.value) expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil) if exp > d.exp { value = value.Quo(value, expScale) } else if exp < d.exp { value = value.Mul(value, expScale) } return Decimal{ value: value, exp: exp, } }
func binaryIntOp(x *big.Int, op token.Token, y *big.Int) interface{} { var z big.Int switch op { case token.ADD: return z.Add(x, y) case token.SUB: return z.Sub(x, y) case token.MUL: return z.Mul(x, y) case token.QUO: return z.Quo(x, y) case token.REM: return z.Rem(x, y) case token.AND: return z.And(x, y) case token.OR: return z.Or(x, y) case token.XOR: return z.Xor(x, y) case token.AND_NOT: return z.AndNot(x, y) case token.SHL: panic("unimplemented") case token.SHR: panic("unimplemented") case token.EQL: return x.Cmp(y) == 0 case token.NEQ: return x.Cmp(y) != 0 case token.LSS: return x.Cmp(y) < 0 case token.LEQ: return x.Cmp(y) <= 0 case token.GTR: return x.Cmp(y) > 0 case token.GEQ: return x.Cmp(y) >= 0 } panic("unreachable") }
// bigRatToValue converts 'number' to an SQL value with SQL type: valueType. // If valueType is integral it truncates 'number' to the integer part according to the // semantics of the big.Rat.Int method. func bigRatToValue(number *big.Rat, valueType querypb.Type) sqltypes.Value { var numberAsBytes []byte switch { case sqltypes.IsIntegral(valueType): // 'number.Num()' returns a reference to the numerator of 'number'. // We copy it here to avoid changing 'number'. truncatedNumber := new(big.Int).Set(number.Num()) truncatedNumber.Quo(truncatedNumber, number.Denom()) numberAsBytes = bigIntToSliceOfBytes(truncatedNumber) case sqltypes.IsFloat(valueType): // Truncate to the closest 'float'. // There's not much we can do if there isn't an exact representation. numberAsFloat64, _ := number.Float64() numberAsBytes = strconv.AppendFloat([]byte{}, numberAsFloat64, 'f', -1, 64) default: panic(fmt.Sprintf("Unsupported type: %v", valueType)) } result, err := sqltypes.ValueFromBytes(valueType, numberAsBytes) if err != nil { panic(fmt.Sprintf("sqltypes.ValueFromBytes failed with: %v", err)) } return result }
// rescale returns a rescaled version of the decimal. Returned // decimal may be less precise if the given exponent is bigger // than the initial exponent of the Decimal. // NOTE: this will truncate, NOT round // // Example: // // d := New(12345, -4) // d2 := d.rescale(-1) // d3 := d2.rescale(-4) // println(d1) // println(d2) // println(d3) // // Output: // // 1.2345 // 1.2 // 1.2000 // func (d Decimal) rescale(exp int32) Decimal { d.ensureInitialized() if exp < -MaxFractionDigits-1 { // Limit the number of digits but we can not call Round here because it is called by Round. // Limit it to MaxFractionDigits + 1 to make sure the final result is correct. exp = -MaxFractionDigits - 1 } // Must convert exps to float64 before - to prevent overflow. diff := math.Abs(float64(exp) - float64(d.exp)) value := new(big.Int).Set(d.value) expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil) if exp > d.exp { value = value.Quo(value, expScale) } else if exp < d.exp { value = value.Mul(value, expScale) } return Decimal{ value: value, exp: exp, fracDigits: d.fracDigits, } }
func _pollardFactoring(task *Task, toFactor *big.Int) []*big.Int { buffer := make([]*big.Int, 0) quo := new(big.Int) quo.Set(toFactor) //~ f := get_f(task.toFactor) for !quo.ProbablyPrime(prime_precision) { //quo.Cmp(big.NewInt(1)) > 0) { if task.ShouldStop() { return buffer } var factor *big.Int var error bool for i := 0; ; i++ { factor, error = pollardRho(task, quo, int64(i)) if task.ShouldStop() { return buffer } if !error { break } } if !factor.ProbablyPrime(prime_precision) { sub := _pollardFactoring(task, factor) buffer = append(buffer, sub...) } else { buffer = append(buffer, factor) } quo.Quo(quo, factor) } return append(buffer, quo) }
// binaryOpConst returns the result of the constant evaluation x op y; // both operands must be of the same "kind" (boolean, numeric, or string). // If intDiv is true, division (op == token.QUO) is using integer division // (and the result is guaranteed to be integer) rather than floating-point // division. Division by zero leads to a run-time panic. // func binaryOpConst(x, y interface{}, op token.Token, intDiv bool) interface{} { x, y = matchConst(x, y) switch x := x.(type) { case bool: y := y.(bool) switch op { case token.LAND: return x && y case token.LOR: return x || y default: unreachable() } case int64: y := y.(int64) switch op { case token.ADD: // TODO(gri) can do better than this if is63bit(x) && is63bit(y) { return x + y } return normalizeIntConst(new(big.Int).Add(big.NewInt(x), big.NewInt(y))) case token.SUB: // TODO(gri) can do better than this if is63bit(x) && is63bit(y) { return x - y } return normalizeIntConst(new(big.Int).Sub(big.NewInt(x), big.NewInt(y))) case token.MUL: // TODO(gri) can do better than this if is32bit(x) && is32bit(y) { return x * y } return normalizeIntConst(new(big.Int).Mul(big.NewInt(x), big.NewInt(y))) case token.REM: return x % y case token.QUO: if intDiv { return x / y } return normalizeRatConst(new(big.Rat).SetFrac(big.NewInt(x), big.NewInt(y))) case token.AND: return x & y case token.OR: return x | y case token.XOR: return x ^ y case token.AND_NOT: return x &^ y default: unreachable() } case *big.Int: y := y.(*big.Int) var z big.Int switch op { case token.ADD: z.Add(x, y) case token.SUB: z.Sub(x, y) case token.MUL: z.Mul(x, y) case token.REM: z.Rem(x, y) case token.QUO: if intDiv { z.Quo(x, y) } else { return normalizeRatConst(new(big.Rat).SetFrac(x, y)) } case token.AND: z.And(x, y) case token.OR: z.Or(x, y) case token.XOR: z.Xor(x, y) case token.AND_NOT: z.AndNot(x, y) default: unreachable() } return normalizeIntConst(&z) case *big.Rat: y := y.(*big.Rat) var z big.Rat switch op { case token.ADD: z.Add(x, y) case token.SUB: z.Sub(x, y) case token.MUL: z.Mul(x, y) case token.QUO: z.Quo(x, y) default: unreachable() } return normalizeRatConst(&z) case complex: y := y.(complex) a, b := x.re, x.im c, d := y.re, y.im var re, im big.Rat switch op { case token.ADD: // (a+c) + i(b+d) re.Add(a, c) im.Add(b, d) case token.SUB: // (a-c) + i(b-d) re.Sub(a, c) im.Sub(b, d) case token.MUL: // (ac-bd) + i(bc+ad) var ac, bd, bc, ad big.Rat ac.Mul(a, c) bd.Mul(b, d) bc.Mul(b, c) ad.Mul(a, d) re.Sub(&ac, &bd) im.Add(&bc, &ad) case token.QUO: // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd var ac, bd, bc, ad, s big.Rat ac.Mul(a, c) bd.Mul(b, d) bc.Mul(b, c) ad.Mul(a, d) s.Add(c.Mul(c, c), d.Mul(d, d)) re.Add(&ac, &bd) re.Quo(&re, &s) im.Sub(&bc, &ad) im.Quo(&im, &s) default: unreachable() } return normalizeComplexConst(complex{&re, &im}) case string: if op == token.ADD { return x + y.(string) } } unreachable() return nil }
// Sqrt sets z to the square root of x and returns z. // The precision of Sqrt is determined by z's Context. // Sqrt will panic on negative values since Big cannot // represent imaginary numbers. func (z *Big) Sqrt(x *Big) *Big { if x.SignBit() { panic("math.Sqrt: cannot take square root of negative number") } switch { case x.form == inf: z.form = inf return z case x.Sign() == 0: z.form = zero return z } // First fast path---check if x is a perfect square. If it is, we can avoid // having to inflate x and can possibly use can use the hardware SQRT. // Note that we can only catch perfect squares that aren't big.Ints. if sq, ok := perfectSquare(x); ok { z.ctx = x.ctx return z.SetMantScale(sq, 0) } zp := z.ctx.prec() // Temporary inflation. Should be enough to accurately determine the sqrt // with at least zp digits after the radix. zpadj := int(zp) << 1 var tmp *Big if z != x { zctx := z.ctx tmp = z.Set(x) tmp.ctx = zctx } else { tmp = new(Big).Set(x) } if !shiftRadixRight(tmp, zpadj) { z.form = inf return z } // Second fast path. Check to see if we can calculate the square root without // using big.Int if !x.IsBig() && zpadj <= 19 { n := tmp.Int64() ix := n >> uint((arith.BitLen(n)+1)>>1) var p int64 for { p = ix ix += n / ix ix >>= 1 if ix == p { return z.SetMantScale(ix, zp) } } } // x isn't a perfect square or x is a big.Int n := tmp.Int() ix := new(big.Int).Rsh(n, uint((n.BitLen()+1)>>1)) var a, p big.Int for { p.Set(ix) ix.Add(ix, a.Quo(n, ix)).Rsh(ix, 1) if ix.Cmp(&p) == 0 { return z.SetBigMantScale(ix, zp) } } }
// Post-order traversal, equivalent to postfix notation. func Eval(node interface{}) (*big.Int, error) { switch nn := node.(type) { case *ast.BinaryExpr: z := new(big.Int) x, xerr := Eval(nn.X) if xerr != nil { return nil, xerr } y, yerr := Eval(nn.Y) if yerr != nil { return nil, yerr } switch nn.Op { case token.ADD: return z.Add(x, y), nil case token.SUB: return z.Sub(x, y), nil case token.MUL: return z.Mul(x, y), nil case token.QUO: if y.Sign() == 0 { // 0 denominator return nil, DivideByZero } return z.Quo(x, y), nil case token.REM: if y.Sign() == 0 { return nil, DivideByZero } return z.Rem(x, y), nil case token.AND: return z.And(x, y), nil case token.OR: return z.Or(x, y), nil case token.XOR: return z.Xor(x, y), nil case token.SHL: if y.Sign() < 0 { // negative shift return nil, NegativeShift } return z.Lsh(x, uint(y.Int64())), nil case token.SHR: if y.Sign() < 0 { return nil, NegativeShift } return z.Rsh(x, uint(y.Int64())), nil case token.AND_NOT: return z.AndNot(x, y), nil default: return nil, UnknownOpErr } case *ast.UnaryExpr: var z *big.Int var err error if z, err = Eval(nn.X); err != nil { return nil, err } switch nn.Op { case token.SUB: // -x return z.Neg(z), nil case token.XOR: // ^x return z.Not(z), nil case token.ADD: // +x (useless) return z, nil } case *ast.BasicLit: z := new(big.Int) switch nn.Kind { case token.INT: z.SetString(nn.Value, 0) return z, nil default: return nil, UnknownLitErr } case *ast.ParenExpr: z, err := Eval(nn.X) if err != nil { return nil, err } return z, nil case *ast.CallExpr: ident, ok := nn.Fun.(*ast.Ident) if !ok { return nil, UnknownTokenErr // quarter to four am; dunno correct error } var f Func f, ok = FuncMap[ident.Name] if !ok { return nil, UnknownFuncErr } var aerr error args := make([]*big.Int, len(nn.Args)) for i, a := range nn.Args { if args[i], aerr = Eval(a); aerr != nil { return nil, aerr } } x, xerr := f(args...) if xerr != nil { return nil, xerr } return x, nil } return nil, UnknownTokenErr }