示例#1
0
文件: const.go 项目: kelsieflynn/llgo
// Convert attempts to convert the constant x to a given type.
// If the attempt is successful, the result is the new constant;
// otherwise the result is invalid.
func (x Const) Convert(typ *Type) Const {
	// TODO(gri) implement this
	switch x := x.Val.(type) {
	//case bool:
	case *big.Int:
		switch Underlying(*typ) {
		case Float32, Float64:
			var z big.Rat
			z.SetInt(x)
			return Const{&z}
		case String:
			return Const{string(x.Int64())}
		case Complex64, Complex128:
			var z big.Rat
			z.SetInt(x)
			return Const{Cmplx{&z, &big.Rat{}}}
		}
	case *big.Rat:
		switch Underlying(*typ) {
		case Byte, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Int64, Uint64:
			// Convert to an integer. Remove the fractional component.
			num, denom := x.Num(), x.Denom()
			var z big.Int
			z.Quo(num, denom)
			return Const{&z}
		}
		//case Cmplx:
		//case string:
	}
	//panic("unimplemented")
	return x
}
示例#2
0
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")
}
示例#3
0
文件: main.go 项目: seikichi/gopl
func renderRat(img *image.RGBA) {
	var yminR, ymaxMinR, heightR big.Rat
	yminR.SetInt64(ymin)
	ymaxMinR.SetInt64(ymax - ymin)
	heightR.SetInt64(height)

	var xminR, xmaxMinR, widthR big.Rat
	xminR.SetInt64(xmin)
	xmaxMinR.SetInt64(xmax - xmin)
	widthR.SetInt64(width)

	var y, x big.Rat
	for py := int64(0); py < height; py++ {
		// y := float64(py)/height*(ymax-ymin) + ymin
		y.SetInt64(py)
		y.Quo(&y, &heightR)
		y.Mul(&y, &ymaxMinR)
		y.Add(&y, &yminR)

		for px := int64(0); px < width; px++ {
			// x := float64(px)/width*(xmax-xmin) + xmin
			x.SetInt64(px)
			x.Quo(&x, &widthR)
			x.Mul(&x, &xmaxMinR)
			x.Add(&x, &xminR)

			c := mandelbrotRat(&x, &y)
			if c == nil {
				c = color.Black
			}
			img.Set(int(px), int(py), c)
		}
	}
}
示例#4
0
// Total returns the total of an Usage
func (u *Usage) Total() *big.Rat {
	//return math.Min(u.Object.UnitPrice * u.BillableQuantity(), u.Object.UnitPriceCap)

	total := new(big.Rat).Mul(u.BillableQuantity(), u.Object.UnitPrice)
	total = total.Quo(total, u.Object.UnitQuantity)
	return ratMin(total, u.Object.UnitPriceCap)
}
示例#5
0
func String(v xdr.Int64) string {
	var f, o, r big.Rat

	f.SetInt64(int64(v))
	o.SetInt64(One)
	r.Quo(&f, &o)

	return r.FloatString(7)
}
示例#6
0
func GasPrice(bp, gl, ep *big.Int) *big.Int {
	BP := new(big.Rat).SetInt(bp)
	GL := new(big.Rat).SetInt(gl)
	EP := new(big.Rat).SetInt(ep)
	GP := new(big.Rat).Quo(BP, GL)
	GP = GP.Quo(GP, EP)

	return GP.Mul(GP, etherInWei).Num()
}
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)))
}
示例#8
0
// floatString returns the string representation for a
// numeric value v in normalized floating-point format.
func floatString(v exact.Value) string {
	if exact.Sign(v) == 0 {
		return "0.0"
	}
	// x != 0

	// convert |v| into a big.Rat x
	x := new(big.Rat).SetFrac(absInt(exact.Num(v)), absInt(exact.Denom(v)))

	// normalize x and determine exponent e
	// (This is not very efficient, but also not speed-critical.)
	var e int
	for x.Cmp(ten) >= 0 {
		x.Quo(x, ten)
		e++
	}
	for x.Cmp(one) < 0 {
		x.Mul(x, ten)
		e--
	}

	// TODO(gri) Values such as 1/2 are easier to read in form 0.5
	// rather than 5.0e-1. Similarly, 1.0e1 is easier to read as
	// 10.0. Fine-tune best exponent range for readability.

	s := x.FloatString(100) // good-enough precision

	// trim trailing 0's
	i := len(s)
	for i > 0 && s[i-1] == '0' {
		i--
	}
	s = s[:i]

	// add a 0 if the number ends in decimal point
	if len(s) > 0 && s[len(s)-1] == '.' {
		s += "0"
	}

	// add exponent and sign
	if e != 0 {
		s += fmt.Sprintf("e%+d", e)
	}
	if exact.Sign(v) < 0 {
		s = "-" + s
	}

	// TODO(gri) If v is a "small" fraction (i.e., numerator and denominator
	// are just a small number of decimal digits), add the exact fraction as
	// a comment. For instance: 3.3333...e-1 /* = 1/3 */

	return s
}
示例#9
0
文件: geophoto.go 项目: v64/geophoto
func sexToDec(deg, min, sec *big.Rat, dir string) *big.Rat {
	// sexagesimal (base 60) to decimal
	// https://imm.dtf.wa.gov.au/helpfiles/Latitude_Longitude_conversion_hlp.htm

	deg.Add(deg, min.Quo(min, big.NewRat(60, 1)))
	deg.Add(deg, sec.Quo(sec, big.NewRat(3600, 1)))

	// N and E are the positive directions (like on an x,y axis)
	if dir == "S" || dir == "W" {
		deg.Neg(deg)
	}

	return deg
}
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)))
}
示例#11
0
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")
}
示例#12
0
文件: bigrat.go 项目: zzn01/ivy
// ratScale multiplies x by 10**exp.
func ratScale(x *big.Rat, exp int) {
	if exp < 0 {
		x.Inv(x)
		ratScale(x, -exp)
		x.Inv(x)
		return
	}
	for exp >= 9 {
		x.Quo(x, bigRatBillion)
		exp -= 9
	}
	for exp >= 1 {
		x.Quo(x, bigRatTen)
		exp--
	}
}
示例#13
0
func sqrtFloat(x *big.Rat) *big.Rat {
	t1 := new(big.Rat)
	t2 := new(big.Rat)
	t1.Set(x)

	// Iterate.
	// x{n} = (x{n-1}+x{0}/x{n-1}) / 2
	for i := 0; i <= 4; i++ {
		if t1.Cmp(zero) == 0 {
			return t1
		}
		t2.Quo(x, t1)
		t2.Add(t2, t1)
		t1.Mul(half, t2)
	}

	return t1
}
示例#14
0
文件: bigrat.go 项目: zzn01/ivy
// ratExponent returns the power of ten that x would display in scientific notation.
func ratExponent(x *big.Rat) int {
	if x.Sign() < 0 {
		x.Neg(x)
	}
	e := 0
	invert := false
	if x.Num().Cmp(x.Denom()) < 0 {
		invert = true
		x.Inv(x)
		e++
	}
	for x.Cmp(bigRatBillion) >= 0 {
		e += 9
		x.Quo(x, bigRatBillion)
	}
	for x.Cmp(bigRatTen) > 0 {
		e++
		x.Quo(x, bigRatTen)
	}
	if invert {
		return -e
	}
	return e
}
示例#15
0
文件: const.go 项目: strickyak/goterp
// 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
}
示例#16
0
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)
		}
	}
}
示例#17
0
// Contract evaluation is done here.
func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, block *ethutil.Block, cb TxCallback) {
	// Instruction pointer
	pc := 0
	blockInfo := bm.BlockInfo(block)

	contract := block.GetContract(tx.Hash())
	if contract == nil {
		fmt.Println("Contract not found")
		return
	}

	Pow256 := ethutil.BigPow(2, 256)

	//fmt.Printf("#   op   arg\n")
out:
	for {
		// The base big int for all calculations. Use this for any results.
		base := new(big.Int)
		// XXX Should Instr return big int slice instead of string slice?
		// Get the next instruction from the contract
		//op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc)))))
		nb := ethutil.NumberToBytes(uint64(pc), 32)
		o, _, _ := ethutil.Instr(contract.State().Get(string(nb)))
		op := OpCode(o)

		if !cb(0) {
			break
		}

		if Debug {
			//fmt.Printf("%-3d %-4s\n", pc, op.String())
		}

		switch op {
		case oSTOP:
			break out
		case oADD:
			x, y := bm.stack.Popn()
			// (x + y) % 2 ** 256
			base.Add(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSUB:
			x, y := bm.stack.Popn()
			// (x - y) % 2 ** 256
			base.Sub(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oMUL:
			x, y := bm.stack.Popn()
			// (x * y) % 2 ** 256
			base.Mul(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oDIV:
			x, y := bm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSDIV:
			x, y := bm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Div(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			bm.stack.Push(z)
		case oMOD:
			x, y := bm.stack.Popn()
			base.Mod(x, y)
			bm.stack.Push(base)
		case oSMOD:
			x, y := bm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Mod(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			bm.stack.Push(z)
		case oEXP:
			x, y := bm.stack.Popn()
			base.Exp(x, y, Pow256)

			bm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, bm.stack.Pop())
			bm.stack.Push(base)
		case oLT:
			x, y := bm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := bm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := bm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := bm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := bm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}

		// Please note  that the  following code contains some
		// ugly string casting. This will have to change to big
		// ints. TODO :)
		case oMYADDRESS:
			bm.stack.Push(ethutil.BigD(tx.Hash()))
		case oTXSENDER:
			bm.stack.Push(ethutil.BigD(tx.Sender()))
		case oTXVALUE:
			bm.stack.Push(tx.Value)
		case oTXDATAN:
			bm.stack.Push(big.NewInt(int64(len(tx.Data))))
		case oTXDATA:
			v := bm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 {
				bm.stack.Push(ethutil.Big("0"))
			} else {
				bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			bm.stack.Push(ethutil.Big(block.PrevHash))
		case oBLK_COINBASE:
			bm.stack.Push(ethutil.Big(block.Coinbase))
		case oBLK_TIMESTAMP:
			bm.stack.Push(big.NewInt(block.Time))
		case oBLK_NUMBER:
			bm.stack.Push(blockInfo.Number)
		case oBLK_DIFFICULTY:
			bm.stack.Push(block.Difficulty)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(block.Difficulty)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			bm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(bm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			if op == oSHA256 {
				bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
			} else if op == oSHA3 {
				bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
			} else {
				bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
			}
		case oECMUL:
			y := bm.stack.Pop()
			x := bm.stack.Pop()
			//n := bm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				bm.stack.Push(ethutil.Big("0"))
				bm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	bm.stack.Push("0")
			//	bm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			bm.stack.Push(bm.mem[strconv.Itoa(pc)])
		case oPOP:
			// Pop current value of the stack
			bm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := bm.stack.Pop()
			bm.stack.Push(x)
			bm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := bm.stack.Popn()
			bm.stack.Push(y)
			bm.stack.Push(x)
		case oMLOAD:
			x := bm.stack.Pop()
			bm.stack.Push(bm.mem[x.String()])
		case oMSTORE:
			x, y := bm.stack.Popn()
			bm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := bm.stack.Pop()
			// decode the object as a big integer
			decoder := ethutil.NewRlpDecoder([]byte(contract.State().Get(x.String())))
			if !decoder.IsNil() {
				bm.stack.Push(decoder.AsBigInt())
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			x, y := bm.stack.Popn()
			contract.State().Update(x.String(), string(ethutil.Encode(y)))
		case oJMP:
			x := int(bm.stack.Pop().Uint64())
			// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
			pc = x
			pc--
		case oJMPI:
			x := bm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			bm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := bm.stack.Pop()
			contractAddr := bm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			bm.stack.Push(getContractMemory(block, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			d := block.State().Get(bm.stack.Pop().String())
			ether := ethutil.NewEtherFromData([]byte(d))
			bm.stack.Push(ether.Amount)
		case oMKTX:
			value, addr := bm.stack.Popn()
			from, length := bm.stack.Popn()

			j := 0
			dataItems := make([]string, int(length.Uint64()))
			for i := from.Uint64(); i < length.Uint64(); i++ {
				dataItems[j] = string(bm.mem[strconv.Itoa(int(i))].Bytes())
				j++
			}
			// TODO sign it?
			tx := ethutil.NewTransaction(string(addr.Bytes()), value, dataItems)
			// Add the transaction to the tx pool
			bm.server.txPool.QueueTransaction(tx)
		case oSUICIDE:
			//addr := bm.stack.Pop()
		}
		pc++
	}

	bm.stack.Print()
}
示例#18
0
//export OFXTransactionCallback
func OFXTransactionCallback(transaction_data C.struct_OfxTransactionData, data unsafe.Pointer) C.int {
	iobj := (*ImportObject)(data)
	itl := iobj.TransactionList
	transaction := new(Transaction)

	if transaction_data.name_valid != 0 {
		transaction.Description = C.GoString(&transaction_data.name[0])
	}
	//	if transaction_data.reference_number_valid != 0 {
	//		fmt.Println("reference_number: ", C.GoString(&transaction_data.reference_number[0]))
	//	}
	if transaction_data.date_posted_valid != 0 {
		transaction.Date = time.Unix(int64(transaction_data.date_posted), 0)
	} else if transaction_data.date_initiated_valid != 0 {
		transaction.Date = time.Unix(int64(transaction_data.date_initiated), 0)
	}
	if transaction_data.fi_id_valid != 0 {
		transaction.RemoteId = C.GoString(&transaction_data.fi_id[0])
	}

	if transaction_data.amount_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(transaction_data.amount))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		if transaction_data.memo_valid != 0 {
			split.Memo = C.GoString(&transaction_data.memo[0])
		}
		if transaction_data.check_number_valid != 0 {
			split.Number = C.GoString(&transaction_data.check_number[0])
		}
		split.SecurityId = -1
		split.AccountId = itl.Account.AccountId
		transaction.Splits = append(transaction.Splits, split)
	} else {
		if iobj.Error == nil {
			iobj.Error = errors.New("OFX transaction amount invalid")
		}
		return 1
	}

	var security *Security
	var err error
	split := new(Split)
	units := new(big.Rat)

	if transaction_data.units_valid != 0 {
		units.SetFloat64(float64(transaction_data.units))
		if transaction_data.security_data_valid != 0 {
			security_data := transaction_data.security_data_ptr
			if security_data.ticker_valid != 0 {
				s, err := GetSecurityByName(C.GoString(&security_data.ticker[0]))
				if err != nil {
					if iobj.Error == nil {
						iobj.Error = errors.New("Failed to find OFX transaction security: " + C.GoString(&security_data.ticker[0]))
					}
					return 1
				}
				security = s
			} else {
				if iobj.Error == nil {
					iobj.Error = errors.New("OFX security ticker invalid")
				}
				return 1
			}
			if security.Type == Stock && security_data.unique_id_valid != 0 && security_data.unique_id_type_valid != 0 && C.GoString(&security_data.unique_id_type[0]) == "CUSIP" {
				// Validate the security CUSIP, if possible
				if security.AlternateId != C.GoString(&security_data.unique_id[0]) {
					if iobj.Error == nil {
						iobj.Error = errors.New("OFX transaction security CUSIP failed to validate")
					}
					return 1
				}
			}
		} else {
			security, err = GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
			if err != nil {
				if iobj.Error == nil {
					iobj.Error = err
				}
				return 1
			}
		}
	} else {
		// Calculate units from other available fields if its not present
		//		units = - (amount + various fees) / unitprice
		units.SetFloat64(float64(transaction_data.amount))
		fees := new(big.Rat)
		if transaction_data.fees_valid != 0 {
			fees.SetFloat64(float64(-transaction_data.fees))
		}
		if transaction_data.commission_valid != 0 {
			commission := new(big.Rat)
			commission.SetFloat64(float64(-transaction_data.commission))
			fees.Add(fees, commission)
		}
		units.Add(units, fees)
		units.Neg(units)
		if transaction_data.unitprice_valid != 0 && transaction_data.unitprice != 0 {
			unitprice := new(big.Rat)
			unitprice.SetFloat64(float64(transaction_data.unitprice))
			units.Quo(units, unitprice)
		}

		// If 'units' wasn't present, assume we're using the account's security
		security, err = GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
	}

	split.Amount = units.FloatString(security.Precision)
	split.SecurityId = security.SecurityId
	split.AccountId = -1
	transaction.Splits = append(transaction.Splits, split)

	if transaction_data.fees_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(-transaction_data.fees))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		split.Memo = "fees"
		split.SecurityId = itl.Account.SecurityId
		split.AccountId = -1
		transaction.Splits = append(transaction.Splits, split)
	}

	if transaction_data.commission_valid != 0 {
		split := new(Split)
		r := new(big.Rat)
		r.SetFloat64(float64(-transaction_data.commission))
		security, err := GetSecurity(itl.Account.SecurityId, itl.Account.UserId)
		if err != nil {
			if iobj.Error == nil {
				iobj.Error = err
			}
			return 1
		}
		split.Amount = r.FloatString(security.Precision)
		split.Memo = "commission"
		split.SecurityId = itl.Account.SecurityId
		split.AccountId = -1
		transaction.Splits = append(transaction.Splits, split)
	}

	//	if transaction_data.payee_id_valid != 0 {
	//		fmt.Println("payee_id: ", C.GoString(&transaction_data.payee_id[0]))
	//	}

	transaction_list := append(*itl.Transactions, *transaction)
	iobj.TransactionList.Transactions = &transaction_list

	return 0
}
示例#19
0
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
}
示例#20
0
文件: ops.go 项目: juanman2/dot-emacs
				s.fatalf("cannot convert %q to int", p)
			}
			s.pushX(i)
		}},
	},
	// rational literal
	{
		regex(floatPat + "/" + floatPat),
		genericOp{0, 1, func(s *stack, p string) {
			i := strings.Index(p, "/")
			r0, ok0 := new(big.Rat).SetString(p[0:i])
			r1, ok1 := new(big.Rat).SetString(p[i+1:])
			if !ok0 || !ok1 {
				s.fatalf("bad rational %q", p)
			}
			s.pushX(r0.Quo(r0, r1))
		}},
	},
	// float literal
	{
		regex(floatPat),
		genericOp{0, 1, func(s *stack, p string) {
			v, err := strconv.ParseFloat(p, 64)
			if err != nil {
				s.fatalf("bad float number %q", p)
			}
			s.pushX(v)
		}},
	},
	// rune literal
	{
示例#21
0
文件: vm.go 项目: GrimDerp/eth-go
func (vm *Vm) Process(contract *Contract, state *State, vars RuntimeVars) {
	vm.mem = make(map[string]*big.Int)
	vm.stack = NewStack()

	addr := vars.address // tx.Hash()[12:]
	// Instruction pointer
	pc := 0

	if contract == nil {
		fmt.Println("Contract not found")
		return
	}

	Pow256 := ethutil.BigPow(2, 256)

	if ethutil.Config.Debug {
		ethutil.Config.Log.Debugf("#   op\n")
	}

	stepcount := 0
	totalFee := new(big.Int)

out:
	for {
		stepcount++
		// The base big int for all calculations. Use this for any results.
		base := new(big.Int)
		val := contract.GetMem(pc)
		//fmt.Printf("%x = %d, %v %x\n", r, len(r), v, nb)
		op := OpCode(val.Uint())

		var fee *big.Int = new(big.Int)
		var fee2 *big.Int = new(big.Int)
		if stepcount > 16 {
			fee.Add(fee, StepFee)
		}

		// Calculate the fees
		switch op {
		case oSSTORE:
			y, x := vm.stack.Peekn()
			val := contract.Addr(ethutil.BigToBytes(x, 256))
			if val.IsEmpty() && len(y.Bytes()) > 0 {
				fee2.Add(DataFee, StoreFee)
			} else {
				fee2.Sub(DataFee, StoreFee)
			}
		case oSLOAD:
			fee.Add(fee, StoreFee)
		case oEXTRO, oBALANCE:
			fee.Add(fee, ExtroFee)
		case oSHA256, oRIPEMD160, oECMUL, oECADD, oECSIGN, oECRECOVER, oECVALID:
			fee.Add(fee, CryptoFee)
		case oMKTX:
			fee.Add(fee, ContractFee)
		}

		tf := new(big.Int).Add(fee, fee2)
		if contract.Amount.Cmp(tf) < 0 {
			fmt.Println("Insufficient fees to continue running the contract", tf, contract.Amount)
			break
		}
		// Add the fee to the total fee. It's subtracted when we're done looping
		totalFee.Add(totalFee, tf)

		if ethutil.Config.Debug {
			ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
		}

		switch op {
		case oSTOP:
			fmt.Println("")
			break out
		case oADD:
			x, y := vm.stack.Popn()
			// (x + y) % 2 ** 256
			base.Add(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oSUB:
			x, y := vm.stack.Popn()
			// (x - y) % 2 ** 256
			base.Sub(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oMUL:
			x, y := vm.stack.Popn()
			// (x * y) % 2 ** 256
			base.Mul(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oDIV:
			x, y := vm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oSDIV:
			x, y := vm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Div(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			vm.stack.Push(z)
		case oMOD:
			x, y := vm.stack.Popn()
			base.Mod(x, y)
			vm.stack.Push(base)
		case oSMOD:
			x, y := vm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Mod(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			vm.stack.Push(z)
		case oEXP:
			x, y := vm.stack.Popn()
			base.Exp(x, y, Pow256)

			vm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, vm.stack.Pop())
			vm.stack.Push(base)
		case oLT:
			x, y := vm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := vm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := vm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := vm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := vm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oMYADDRESS:
			vm.stack.Push(ethutil.BigD(addr))
		case oTXSENDER:
			vm.stack.Push(ethutil.BigD(vars.sender))
		case oTXVALUE:
			vm.stack.Push(vars.txValue)
		case oTXDATAN:
			vm.stack.Push(big.NewInt(int64(len(vars.txData))))
		case oTXDATA:
			v := vm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(vars.txData)))) >= 0 {
				vm.stack.Push(ethutil.Big("0"))
			} else {
				vm.stack.Push(ethutil.Big(vars.txData[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			vm.stack.Push(ethutil.BigD(vars.prevHash))
		case oBLK_COINBASE:
			vm.stack.Push(ethutil.BigD(vars.coinbase))
		case oBLK_TIMESTAMP:
			vm.stack.Push(big.NewInt(vars.time))
		case oBLK_NUMBER:
			vm.stack.Push(big.NewInt(int64(vars.blockNumber)))
		case oBLK_DIFFICULTY:
			vm.stack.Push(vars.diff)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(vars.diff)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			vm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(vm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(vm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			if op == oSHA256 {
				vm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
			} else if op == oSHA3 {
				vm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
			} else {
				vm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
			}
		case oECMUL:
			y := vm.stack.Pop()
			x := vm.stack.Pop()
			//n := vm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				vm.stack.Push(ethutil.Big("0"))
				vm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	vm.stack.Push("0")
			//	vm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			vm.stack.Push(contract.GetMem(pc).BigInt())
		case oPOP:
			// Pop current value of the stack
			vm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := vm.stack.Pop()
			vm.stack.Push(x)
			vm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := vm.stack.Popn()
			vm.stack.Push(y)
			vm.stack.Push(x)
		case oMLOAD:
			x := vm.stack.Pop()
			vm.stack.Push(vm.mem[x.String()])
		case oMSTORE:
			x, y := vm.stack.Popn()
			vm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := vm.stack.Pop()
			// decode the object as a big integer
			decoder := contract.Addr(x.Bytes())
			if !decoder.IsNil() {
				vm.stack.Push(decoder.BigInt())
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			y, x := vm.stack.Popn()
			addr := ethutil.BigToBytes(x, 256)
			fmt.Printf(" => %x (%v) @ %v", y.Bytes(), y, ethutil.BigD(addr))
			contract.SetAddr(addr, y)
			//contract.State().Update(string(idx), string(y))
		case oJMP:
			x := int(vm.stack.Pop().Uint64())
			// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
			pc = x
			pc--
		case oJMPI:
			x := vm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			vm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := vm.stack.Pop()
			contractAddr := vm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			vm.stack.Push(contractMemory(state, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			account := state.GetAccount(vm.stack.Pop().Bytes())
			vm.stack.Push(account.Amount)
		case oMKTX:
			addr, value := vm.stack.Popn()
			from, length := vm.stack.Popn()

			makeInlineTx(addr.Bytes(), value, from, length, contract, state)
		case oSUICIDE:
			recAddr := vm.stack.Pop().Bytes()
			// Purge all memory
			deletedMemory := contract.state.Purge()
			// Add refunds to the pop'ed address
			refund := new(big.Int).Mul(StoreFee, big.NewInt(int64(deletedMemory)))
			account := state.GetAccount(recAddr)
			account.Amount.Add(account.Amount, refund)
			// Update the refunding address
			state.UpdateAccount(recAddr, account)
			// Delete the contract
			state.trie.Update(string(addr), "")

			ethutil.Config.Log.Debugf("(%d) => %x\n", deletedMemory, recAddr)
			break out
		default:
			fmt.Printf("Invalid OPCODE: %x\n", op)
		}
		ethutil.Config.Log.Debugln("")
		//vm.stack.Print()
		pc++
	}

	state.UpdateContract(addr, contract)
}
示例#22
0
// 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
}
示例#23
0
// 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))
}
示例#24
0
func Quotient(a, b *big.Rat) big.Rat {
	var q big.Rat
	return Minus(*q.Quo(a, b))
}
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
}