func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} { var z big.Rat 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.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") }
func mandelbrotRat(a, b *big.Rat) color.Color { var x, y, nx, ny, x2, y2, f2, f4, r2, tmp big.Rat f2.SetInt64(2) f4.SetInt64(4) x.SetInt64(0) y.SetInt64(0) defer func() { recover() }() for n := uint8(0); n < iterations; n++ { // Not update x2 and y2 // because they are already updated in the previous loop nx.Sub(&x2, &y2) nx.Add(&nx, a) tmp.Mul(&x, &y) ny.Mul(&f2, &tmp) ny.Add(&ny, b) x.Set(&nx) y.Set(&ny) x2.Mul(&x, &x) y2.Mul(&y, &y) r2.Add(&x2, &y2) if r2.Cmp(&f4) > 0 { return color.Gray{255 - contrast*n} } } return color.Black }
func convertMeasure(in Measure) string { if in == Measure(0) { return "0" } measureNamesKeys := []int{} for m := range measureNames { measureNamesKeys = append(measureNamesKeys, int(m)) } sort.Ints(measureNamesKeys) inInt := int(in) _ = inInt for i := len(measureNamesKeys) - 1; i >= 0; i-- { key := measureNamesKeys[i] if inInt > key { a := big.NewRat(int64(inInt), 256) b := measureNames[Measure(key)].Rat r := new(big.Rat) s := r.Sub(a, b) return b.RatString() + " + " + s.RatString() } } return "not found" }
func applyOp(val *big.Rat, op ast.OpClass, operand *big.Rat) { switch op { case ast.OpAdd: val.Add(val, operand) case ast.OpSubtract: val.Sub(val, operand) default: panic(fmt.Sprintf("eval.applyOp: unkown operand: %d (%s)", op, op)) } }
func Round(r *big.Rat) *big.Rat { d := new(big.Int).Set(r.Denom()) n := new(big.Int).Set(r.Num()) n.Mod(n, d) if new(big.Int).Mul(n, big.NewInt(2)).Cmp(d) >= 0 { r.Add(r, new(big.Rat).SetInt64(1)) } r.Sub(r, new(big.Rat).SetFrac(n, d)) return r }
func tans(m []mTerm) *big.Rat { if len(m) == 1 { return tanEval(m[0].a, big.NewRat(m[0].n, m[0].d)) } half := len(m) / 2 a := tans(m[:half]) b := tans(m[half:]) r := new(big.Rat) return r.Quo(new(big.Rat).Add(a, b), r.Sub(one, r.Mul(a, b))) }
func (z *BigComplex) Mul(x, y *BigComplex) *BigComplex { re := new(big.Rat).Mul(&x.Re, &y.Re) re.Sub(re, new(big.Rat).Mul(&x.Im, &y.Im)) im := new(big.Rat).Mul(&x.Re, &y.Im) im.Add(im, new(big.Rat).Mul(&x.Im, &y.Re)) z.Re = *re z.Im = *im return z }
func tanEval(coef int64, f *big.Rat) *big.Rat { if coef == 1 { return f } if coef < 0 { r := tanEval(-coef, f) return r.Neg(r) } ca := coef / 2 cb := coef - ca a := tanEval(ca, f) b := tanEval(cb, f) r := new(big.Rat) return r.Quo(new(big.Rat).Add(a, b), r.Sub(one, r.Mul(a, b))) }
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') } }
func (me *StatisticalAccumulator) Variance() *big.Rat { variance := new(big.Rat) variance.Inv(me.n) variance.Mul(variance, me.sigmaXISquared) temp := new(big.Rat) temp.Mul(me.n, me.n) temp.Inv(temp) temp.Mul(temp, me.sigmaXI) temp.Mul(temp, me.sigmaXI) variance.Sub(variance, temp) return variance }
// Check the transaction to ensure it is balanced func (t *Transaction) CheckBalance() error { if len(t.Accounts) == 0 { return errors.New("Transaction does not have any accounts") } // Check that they balance balance := new(big.Rat) for _, a := range t.Accounts { if a.Debit { balance.Add(balance, a.Amount) } else { balance.Sub(balance, a.Amount) } } b := balance.FloatString(2) if b != "0.00" { return errors.New(fmt.Sprintf("Transaction does not balance: %s", b)) } return nil }
func binaryCmplxOp(x cmplx, op token.Token, y cmplx) interface{} { a, b := x.re, x.im c, d := y.re, y.im switch op { case token.ADD: // (a+c) + i(b+d) var re, im big.Rat re.Add(a, c) im.Add(b, d) return cmplx{&re, &im} case token.SUB: // (a-c) + i(b-d) var re, im big.Rat re.Sub(a, c) im.Sub(b, d) return cmplx{&re, &im} 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) var re, im big.Rat re.Sub(&ac, &bd) im.Add(&bc, &ad) return cmplx{&re, &im} 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)) var re, im big.Rat re.Add(&ac, &bd) re.Quo(&re, &s) im.Sub(&bc, &ad) im.Quo(&im, &s) return cmplx{&re, &im} case token.EQL: return a.Cmp(c) == 0 && b.Cmp(d) == 0 case token.NEQ: return a.Cmp(c) != 0 || b.Cmp(d) != 0 } panic("unreachable") }
// evaluatePostfix takes a postfix expression and evaluates it func evaluatePostfix(postfix []string) (*big.Rat, error) { var stack stack.Stack result := new(big.Rat) // note: a new(big.Rat) has value "0/1" ie zero for _, token := range postfix { if isOperand(token) { bigrat := new(big.Rat) if _, err := fmt.Sscan(token, bigrat); err != nil { return nil, fmt.Errorf("unable to scan %s", token) } stack.Push(bigrat) } else if isOperator(token) { op2, err2 := stack.Pop() if err2 != nil { return nil, err2 } var op1 interface{} if token != "@" { var err1 error if op1, err1 = stack.Pop(); err1 != nil { return nil, err1 } } dummy := new(big.Rat) switch token { case "**": float1 := BigratToFloat(op1.(*big.Rat)) float2 := BigratToFloat(op2.(*big.Rat)) float_result := math.Pow(float1, float2) stack.Push(FloatToBigrat(float_result)) case "*": result := dummy.Mul(op1.(*big.Rat), op2.(*big.Rat)) stack.Push(result) case "/": result := dummy.Quo(op1.(*big.Rat), op2.(*big.Rat)) stack.Push(result) case "+": result = dummy.Add(op1.(*big.Rat), op2.(*big.Rat)) stack.Push(result) case "-": result = dummy.Sub(op1.(*big.Rat), op2.(*big.Rat)) stack.Push(result) case "<": if op1.(*big.Rat).Cmp(op2.(*big.Rat)) <= -1 { stack.Push(big.NewRat(1, 1)) } else { stack.Push(new(big.Rat)) } case ">": if op1.(*big.Rat).Cmp(op2.(*big.Rat)) >= 1 { stack.Push(big.NewRat(1, 1)) } else { stack.Push(new(big.Rat)) } case "@": result := dummy.Mul(big.NewRat(-1, 1), op2.(*big.Rat)) stack.Push(result) } } else { return nil, fmt.Errorf("unknown token %v", token) } } retval, err := stack.Pop() if err != nil { return nil, err } return retval.(*big.Rat), nil }
// 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 }
func main() { f, err := os.Create("/tmp/profile") if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() p, _ := new(big.Int).SetString("233970423115425145524320034830162017933", 10) a := big.NewInt(-95051) b := big.NewInt(11279326) G := dh.NewEllipticCurve(a, b, p) gx := big.NewInt(182) gy, _ := new(big.Int).SetString("85518893674295321206118380980485522083", 10) g := dh.NewEllipticCurveElement(G, gx, gy) q, _ := new(big.Int).SetString("29246302889428143187362802287225875743", 10) GG := dh.NewGeneratedGroup(G, g, *q) var bias uint = 8 alice := dh.NewBiasedECDSA(GG, bias) var msg = []byte("I was a fiend") key, _ := new(big.Int).SetString("255bf9c75628ab469b45cced58755a3", 16) d := new(big.Rat).SetInt(key) numSigs := 22 B := dh.Matrix(make([]dh.Vector, numSigs+2)) zero := dh.Vector(make([]*big.Rat, numSigs+2)) for i, _ := range zero { zero[i] = new(big.Rat) } for i, _ := range B { B[i] = zero.Copy() } ct := big.NewRat(1, 1<<bias) B[len(B)-2][len(B)-2].Set(ct) cu := new(big.Rat).SetInt(q) cu.Quo(cu, big.NewRat(1<<bias, 1)) B[len(B)-1][len(B)-1].Set(cu) ts := make([]*big.Int, numSigs) us := make([]*big.Int, numSigs) for i := 0; i < numSigs; i++ { B[i][i].SetInt(q) r, s := alice.Sign(msg) t, u := transform(msg, r, s, q, bias) dt := new(big.Int).Mul(key, t) temp := new(big.Int).Sub(u, dt) temp.Mod(temp, q) temp.Sub(q, temp) log.Printf("\ndt: %x\nu: %x\nq-u-dt: %x\nq: %x", dt, u, temp, q) ts[i] = t us[i] = u B[len(B)-2][i] = new(big.Rat).SetInt(t) B[len(B)-1][i] = new(big.Rat).SetInt(u) } check := B[len(B)-1].Copy() check.Sub(B[len(B)-2].Copy().Scale(d)) for i := 0; i < numSigs; i++ { t := ts[i] dt := new(big.Int).Mul(key, t) m := new(big.Int).Div(dt, q) check.Add(B[i].Copy().Scale(new(big.Rat).SetInt(m))) } log.Printf("check=%s", check) B.LLL(big.NewRat(99, 100)) for _, v := range B { if v[len(v)-1].Cmp(cu) == 0 { log.Printf("%s", v) d := new(big.Rat) d.Sub(d, v[len(v)-2]) d.Mul(d, big.NewRat(1<<bias, 1)) guess := dh.Round(d).Num() log.Printf("Recovered key: %x", guess) log.Printf("Correct: %v", guess.Cmp(key) == 0) } } }
func backsub(m Matrix) (Vector, error) { if len(m) == 0 || len(m[0]) < 2 { return Vector{}, nil } coeffs := make(Vector, len(m[0])-1) cnts := make([]int, len(m)) for i := range cnts { cnts[i] = -1 } zero := new(big.Rat) for i := range m { nz := 0 l := len(m[i]) - 1 for j := range m[i][:l] { if m[i][j].Cmp(zero) != 0 { nz++ } } if l-nz == l { return nil, fmt.Errorf("contains a zero row") } cnts[i] = nz } z := make([]index, len(cnts)) for i := range z { z[i].r = i z[i].n = cnts[i] } sort.Sort(indexSlice(z)) for i := range z { r := m[z[i].r] l := len(r) - 1 w := new(big.Rat).Set(r[l]) var v *big.Rat for j := range r[:l] { if r[j].Cmp(zero) == 0 { continue } if coeffs[j] != nil { u := new(big.Rat).Set(coeffs[j]) u.Mul(u, r[j]) w.Sub(w, u) } else if v != nil { return nil, fmt.Errorf("matrix not in rref form") } else { v = new(big.Rat).Set(r[j]) } } if v.Cmp(zero) == 0 { return nil, fmt.Errorf("matrix not in rref form") } coeffs[z[i].r] = w.Quo(w, v) } return coeffs, nil }
// BinaryOp returns the result of the binary expression x op y. // The operation must be defined for the operands. // To force integer division of Int operands, use op == token.QUO_ASSIGN // instead of token.QUO; the result is guaranteed to be Int in this case. // Division by zero leads to a run-time panic. // func BinaryOp(x Value, op token.Token, y Value) Value { x, y = match(x, y) switch x := x.(type) { case unknownVal: return x case boolVal: y := y.(boolVal) switch op { case token.LAND: return x && y case token.LOR: return x || y } case int64Val: a := int64(x) b := int64(y.(int64Val)) var c int64 switch op { case token.ADD: if !is63bit(a) || !is63bit(b) { return normInt(new(big.Int).Add(big.NewInt(a), big.NewInt(b))) } c = a + b case token.SUB: if !is63bit(a) || !is63bit(b) { return normInt(new(big.Int).Sub(big.NewInt(a), big.NewInt(b))) } c = a - b case token.MUL: if !is32bit(a) || !is32bit(b) { return normInt(new(big.Int).Mul(big.NewInt(a), big.NewInt(b))) } c = a * b case token.QUO: return normFloat(new(big.Rat).SetFrac(big.NewInt(a), big.NewInt(b))) case token.QUO_ASSIGN: // force integer division c = a / b case token.REM: c = a % b case token.AND: c = a & b case token.OR: c = a | b case token.XOR: c = a ^ b case token.AND_NOT: c = a &^ b default: goto Error } return int64Val(c) case intVal: a := x.val b := y.(intVal).val var c big.Int switch op { case token.ADD: c.Add(a, b) case token.SUB: c.Sub(a, b) case token.MUL: c.Mul(a, b) case token.QUO: return normFloat(new(big.Rat).SetFrac(a, b)) case token.QUO_ASSIGN: // force integer division c.Quo(a, b) case token.REM: c.Rem(a, b) case token.AND: c.And(a, b) case token.OR: c.Or(a, b) case token.XOR: c.Xor(a, b) case token.AND_NOT: c.AndNot(a, b) default: goto Error } return normInt(&c) case floatVal: a := x.val b := y.(floatVal).val var c big.Rat switch op { case token.ADD: c.Add(a, b) case token.SUB: c.Sub(a, b) case token.MUL: c.Mul(a, b) case token.QUO: c.Quo(a, b) default: goto Error } return normFloat(&c) case complexVal: y := y.(complexVal) 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, cc, dd big.Rat ac.Mul(a, c) bd.Mul(b, d) bc.Mul(b, c) ad.Mul(a, d) cc.Mul(c, c) dd.Mul(d, d) s.Add(&cc, &dd) re.Add(&ac, &bd) re.Quo(&re, &s) im.Sub(&bc, &ad) im.Quo(&im, &s) default: goto Error } return normComplex(&re, &im) case stringVal: if op == token.ADD { return x + y.(stringVal) } } Error: panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y)) }
func (a *EqualSplitsAlgorithm) generateBoundaries() ([]tuple, error) { // generateBoundaries should work for a split_column whose type is integral // (both signed and unsigned) as well as for floating point values. // We perform the calculation of the boundaries using precise big.Rat arithmetic and only // truncate the result in the end if necessary. // We do this since using float64 arithmetic does not have enough precision: // for example, if max=math.MaxUint64 and min=math.MaxUint64-1000 then float64(min)==float64(max). // On the other hand, using integer arithmetic for the case where the split_column is integral // (i.e., rounding (max-min)/split_count to an integer) may cause very dissimilar interval // lengths or a large deviation between split_count and the number of query-parts actually // returned (consider min=0, max=9.5*10^6, and split_count=10^6). // Note(erez): We can probably get away with using big.Float with ~64 bits of precision which // will likely be more efficient. However, we defer optimizing this code until we see if this // is a bottle-neck. minValue, maxValue, err := a.executeMinMaxQuery() if err != nil { return nil, err } // If the table is empty, minValue and maxValue will be NULL. if (minValue.IsNull() && !maxValue.IsNull()) || !minValue.IsNull() && maxValue.IsNull() { panic(fmt.Sprintf("minValue and maxValue must both be NULL or both be non-NULL."+ " minValue: %v, maxValue: %v, splitParams.sql: %v", minValue, maxValue, a.splitParams.sql)) } if minValue.IsNull() { log.Infof("Splitting an empty table. splitParams.sql: %v. Query will not be split.", a.splitParams.sql) return []tuple{}, nil } min, err := valueToBigRat(minValue) if err != nil { panic(fmt.Sprintf("Failed to convert min to a big.Rat: %v, min: %+v", err, min)) } max, err := valueToBigRat(maxValue) if err != nil { panic(fmt.Sprintf("Failed to convert max to a big.Rat: %v, max: %+v", err, max)) } minCmpMax := min.Cmp(max) if minCmpMax > 0 { panic(fmt.Sprintf("max(splitColumn) < min(splitColumn): max:%v, min:%v", max, min)) } if minCmpMax == 0 { log.Infof("max(%v)=min(%v)=%v. splitParams.sql: %v. Query will not be split.", a.splitParams.splitColumns[0], a.splitParams.splitColumns[0], min, a.splitParams.sql) return []tuple{}, nil } // subIntervalSize = (max - min) / a.splitParams.splitCount subIntervalSize := new(big.Rat) subIntervalSize.Sub(max, min) subIntervalSize.Quo(subIntervalSize, new(big.Rat).SetInt64(a.splitParams.splitCount)) boundary := new(big.Rat).Set(min) // Copy min into boundary. var result []tuple for i := int64(1); i < a.splitParams.splitCount; i++ { boundary.Add(boundary, subIntervalSize) // Here boundary=min+i*subIntervalSize boundaryValue := bigRatToValue(boundary, a.splitParams.splitColumnTypes[0]) result = append(result, tuple{boundaryValue}) } return result, nil }