コード例 #1
0
ファイル: basket.go プロジェクト: awesome-docker/scaleway-cli
// Total computes the Usage.Total() of all the Usages of a Basket
func (b *Basket) Total() *big.Rat {
	total := new(big.Rat)
	for _, usage := range *b {
		total = total.Add(total, usage.Total())
	}
	return total
}
コード例 #2
0
ファイル: metapi.go プロジェクト: bonnefoa/gobot
func EstimatePiFromPrevious(iteration, previousIndex int, sum *big.Rat) (*big.Rat, *big.Rat) {
	for i := previousIndex; i < iteration; i++ {
		sum.Add(sum, sn(i))
	}
	pi := getPiFromSum(sum)
	return pi, sum
}
コード例 #3
0
ファイル: complexrat.go プロジェクト: ysohta/gopl-ex
func quo(x, y *complexRat) *complexRat {
	z := newComplexRat()
	denominator := new(big.Rat)
	t := new(big.Rat)
	t.Mul(y.r, y.r)
	denominator.Mul(y.i, y.i)
	denominator.Add(denominator, t)

	if denominator.Cmp(zero) == 0 {
		return newComplexRat()
	}

	ac := new(big.Rat)
	bd := new(big.Rat)
	ac.Mul(x.r, y.r)
	bd.Mul(x.i, y.i)

	bc := new(big.Rat)
	ad := new(big.Rat)
	bc.Mul(x.i, y.r)
	ad.Mul(x.r, y.i)

	z.r.Add(ac, bd)
	z.r.Quo(z.r, denominator)

	z.i.Add(bc, ad.Neg(ad))
	z.i.Quo(z.i, denominator)

	return z
}
コード例 #4
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")
}
コード例 #5
0
ファイル: print.go プロジェクト: kalafut/ledger
// Prints each transaction that matches the given filters.
func PrintRegister(generalLedger []*ledger.Transaction, filterArr []string, columns int) {
	runningBalance := new(big.Rat)
	for _, trans := range generalLedger {
		for _, accChange := range trans.AccountChanges {
			inFilter := len(filterArr) == 0
			for _, filter := range filterArr {
				if strings.Contains(accChange.Name, filter) {
					inFilter = true
				}
			}
			if inFilter {
				runningBalance.Add(runningBalance, accChange.Balance)
				writtenBytes, _ := fmt.Printf("%s %s", trans.Date.Format(ledger.TransactionDateFormat), trans.Payee)
				outBalanceString := accChange.Balance.FloatString(ledger.DisplayPrecision)
				outRunningBalanceString := runningBalance.FloatString(ledger.DisplayPrecision)
				spaceCount := columns - writtenBytes - 2 - len(outBalanceString) - len(outRunningBalanceString)
				if spaceCount < 0 {
					spaceCount = 0
				}
				fmt.Printf("%s%s %s", strings.Repeat(" ", spaceCount), outBalanceString, outRunningBalanceString)
				fmt.Println("")
			}
		}
	}
}
コード例 #6
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)
		}
	}
}
コード例 #7
0
ファイル: server.go プロジェクト: remyoudompheng/gocash
func cumulFlows(flows []*types.Flow) (bals []*types.Amount) {
	x := new(big.Rat)
	for _, f := range flows {
		x = x.Add(x, (*big.Rat)(f.Price))
		bals = append(bals, new(types.Amount).SetRat(x))
	}
	return
}
コード例 #8
0
ファイル: eval.go プロジェクト: albrow/calc
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))
	}
}
コード例 #9
0
ファイル: vector.go プロジェクト: hundt/crypto-challenges
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
}
コード例 #10
0
func runBilling(cmd *Command, rawArgs []string) error {
	if billingHelp {
		return cmd.PrintUsage()
	}
	if len(rawArgs) > 0 {
		return cmd.PrintShortUsage()
	}

	// cli parsing
	args := commands.PsArgs{
		NoTrunc: billingNoTrunc,
	}
	ctx := cmd.GetContext(rawArgs)

	logrus.Warn("")
	logrus.Warn("Warning: 'scw _billing' is a work-in-progress price estimation tool")
	logrus.Warn("For real usage, visit https://cloud.scaleway.com/#/billing")
	logrus.Warn("")

	// table
	w := tabwriter.NewWriter(ctx.Stdout, 20, 1, 3, ' ', 0)
	defer w.Flush()
	fmt.Fprintf(w, "ID\tNAME\tSTARTED\tMONTH PRICE\n")

	// servers
	servers, err := cmd.API.GetServers(true, 0)
	if err != nil {
		return err
	}

	totalMonthPrice := new(big.Rat)

	for _, server := range *servers {
		if server.State != "running" {
			continue
		}
		commercialType := strings.ToLower(server.CommercialType)
		shortID := utils.TruncIf(server.Identifier, 8, !args.NoTrunc)
		shortName := utils.TruncIf(utils.Wordify(server.Name), 25, !args.NoTrunc)
		modificationTime, _ := time.Parse("2006-01-02T15:04:05.000000+00:00", server.ModificationDate)
		modificationAgo := time.Now().UTC().Sub(modificationTime)
		shortModificationDate := units.HumanDuration(modificationAgo)
		usage := pricing.NewUsageByPath(fmt.Sprintf("/compute/%s/run", commercialType))
		usage.SetStartEnd(modificationTime, time.Now().UTC())

		totalMonthPrice = totalMonthPrice.Add(totalMonthPrice, usage.Total())

		fmt.Fprintf(w, "server/%s/%s\t%s\t%s\t%s\n", commercialType, shortID, shortName, shortModificationDate, usage.TotalString())
	}

	fmt.Fprintf(w, "TOTAL\t\t\t%s\n", pricing.PriceString(totalMonthPrice, "EUR"))

	return nil
}
コード例 #11
0
ファイル: bigcomplex.go プロジェクト: raff/eval
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
}
コード例 #12
0
ファイル: vector.go プロジェクト: hundt/crypto-challenges
func (v1 Vector) Dot(v2 Vector) *big.Rat {
	if len(v1) != len(v2) {
		log.Fatalf("Lengths differ: %d != %d", len(v1), len(v2))
	}
	d := new(big.Rat)
	c := new(big.Rat)
	for i, e := range v1 {
		d.Add(d, c.Mul(e, v2[i]))
	}
	return d
}
コード例 #13
0
ファイル: 80.go プロジェクト: cko/project-euler
func Newt_Sqrt(a *big.Rat, x *big.Rat) *big.Rat {
	for i := 0; i < 12; i++ {
		var quot1 = big.NewRat(1, 1)
		quot1 = quot1.Quo(x, big.NewRat(2, 1))
		var mul = big.NewRat(1, 1)
		mul = mul.Mul(big.NewRat(2, 1), x)
		var quot2 = big.NewRat(1, 1)
		quot2 = quot2.Quo(a, mul)
		x = x.Add(quot1, quot2)
	}
	return x
}
コード例 #14
0
ファイル: complexrat.go プロジェクト: ysohta/gopl-ex
func abs(x *complexRat) *big.Rat {
	r := new(big.Rat)
	i := new(big.Rat)
	r.Set(x.r)
	i.Set(x.i)

	r.Mul(r, x.r) // r^2
	i.Mul(i, x.i) // i^2

	r.Add(r, i) // r^2 + i^2

	return sqrtFloat(r) // sqrt(r^2 + i^2)
}
コード例 #15
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
}
コード例 #16
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")
}
コード例 #17
0
ファイル: complexrat.go プロジェクト: ysohta/gopl-ex
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
}
コード例 #18
0
ファイル: print.go プロジェクト: kalafut/ledger
// Prints out account balances formated to a windows of a width of columns.
// Only shows accounts with names less than or equal to the given depth.
func PrintBalances(accountList []*ledger.Account, printZeroBalances bool, depth, columns int) {
	overallBalance := new(big.Rat)
	for _, account := range accountList {
		accDepth := len(strings.Split(account.Name, ":"))
		if accDepth == 1 {
			overallBalance.Add(overallBalance, account.Balance)
		}
		if (printZeroBalances || account.Balance.Sign() != 0) && (depth < 0 || accDepth <= depth) {
			outBalanceString := account.Balance.FloatString(ledger.DisplayPrecision)
			spaceCount := columns - len(account.Name) - len(outBalanceString)
			fmt.Printf("%s%s%s\n", account.Name, strings.Repeat(" ", spaceCount), outBalanceString)
		}
	}
	fmt.Println(strings.Repeat("-", columns))
	outBalanceString := overallBalance.FloatString(ledger.DisplayPrecision)
	spaceCount := columns - len(outBalanceString)
	fmt.Printf("%s%s\n", strings.Repeat(" ", spaceCount), outBalanceString)
}
コード例 #19
0
ファイル: example_rat_test.go プロジェクト: Greentor/go
// Use the classic continued fraction for e
//     e = [1; 0, 1, 1, 2, 1, 1, ... 2n, 1, 1, ...]
// i.e., for the nth term, use
//     1          if   n mod 3 != 1
//  (n-1)/3 * 2   if   n mod 3 == 1
func recur(n, lim int64) *big.Rat {
	term := new(big.Rat)
	if n%3 != 1 {
		term.SetInt64(1)
	} else {
		term.SetInt64((n - 1) / 3 * 2)
	}

	if n > lim {
		return term
	}

	// Directly initialize frac as the fractional
	// inverse of the result of recur.
	frac := new(big.Rat).Inv(recur(n+1, lim))

	return term.Add(term, frac)
}
コード例 #20
0
ファイル: main.go プロジェクト: seikichi/gopl
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
}
コード例 #21
0
ファイル: eApprox.go プロジェクト: rossfrazier/eApproximator
func eDigits(precisionFactor int, stringLength int) string {
	array := make([]int64, precisionFactor)
	for i := 0; i < precisionFactor; i++ {
		var t int64 = int64(i)
		array[i] = t + 1
	}

	var digitsToMultiply []int64
	var e *big.Rat = big.NewRat(1, 1)

	for i := 1; i <= precisionFactor; i++ {
		digitsToMultiply = array[0:i]
		var digitsProduct int64 = 1
		for x := 0; x < len(digitsToMultiply); x++ {
			digitsProduct = digitsProduct * digitsToMultiply[x]
		}
		var finalProduct *big.Rat = big.NewRat(1, digitsProduct)
		e.Add(e, finalProduct)
	}

	return e.FloatString(stringLength)
}
コード例 #22
0
ファイル: transaction.go プロジェクト: revolvingcow/cash
// 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
}
コード例 #23
0
ファイル: print.go プロジェクト: howeyc/ledger
// PrintRegister prints each transaction that matches the given filters.
func PrintRegister(generalLedger []*ledger.Transaction, filterArr []string, columns int) {
	// Calulate widths for variable-length part of output
	// 3 10-width columns (date, account-change, running-total)
	// 4 spaces
	remainingWidth := columns - (10 * 3) - (4 * 1)
	formatString := fmt.Sprintf("%%-10.10s %%-%[1]d.%[1]ds %%-%[2]d.%[2]ds %%10.10s %%10.10s\n", remainingWidth/3, (remainingWidth/3)*2)

	var otherAccount string
	runningBalance := new(big.Rat)
	for _, trans := range generalLedger {
		for aIdx, accChange := range trans.AccountChanges {
			inFilter := len(filterArr) == 0
			for _, filter := range filterArr {
				if strings.Contains(accChange.Name, filter) {
					inFilter = true

					// Probably not the best way, but we just need to find one other account
					if aIdx > 0 {
						otherAccount = trans.AccountChanges[0].Name
					} else {
						otherAccount = trans.AccountChanges[1].Name
					}
				}
			}
			if inFilter {
				runningBalance.Add(runningBalance, accChange.Balance)
				outBalanceString := accChange.Balance.FloatString(displayPrecision)
				outRunningBalanceString := runningBalance.FloatString(displayPrecision)
				fmt.Printf(formatString,
					trans.Date.Format(transactionDateFormat),
					trans.Payee,
					otherAccount,
					outBalanceString,
					outRunningBalanceString)
			}
		}
	}
}
コード例 #24
0
ファイル: parse.go プロジェクト: howeyc/ledger
// Takes a transaction and balances it. This is mainly to fill in the empty part
// with the remaining balance.
func balanceTransaction(input *Transaction) error {
	balance := new(big.Rat)
	var emptyAccPtr *Account
	var emptyAccIndex int
	for accIndex, accChange := range input.AccountChanges {
		if accChange.Balance == nil {
			if emptyAccPtr != nil {
				return fmt.Errorf("More than one account change empty!")
			}
			emptyAccPtr = &accChange
			emptyAccIndex = accIndex
		} else {
			balance = balance.Add(balance, accChange.Balance)
		}
	}
	if balance.Sign() != 0 {
		if emptyAccPtr == nil {
			return fmt.Errorf("No empty account change to place extra balance!")
		}
		input.AccountChanges[emptyAccIndex].Balance = balance.Neg(balance)
	}
	return nil
}
コード例 #25
0
ファイル: problem57.go プロジェクト: mjwestcott/projecteuler
// How many fractions contain a numerator with more digits than the denominator?
func problem57() int {
	sum := 0           // Number of fractions meeting the description.
	const limit = 1000 // Given in problem description.
	one := new(big.Rat).SetInt64(1)
	two := new(big.Rat).SetInt64(2)

	// result will be re-used each iteration to store the
	// current value of the fractional expansion.
	result := new(big.Rat)
	// tail will be re-used each iteration to store the
	// current value of the repeating component of the expansion.
	// That component is 2, (2 + 1/2), (2 + 1/(2 + 1/2)), ...
	tail := new(big.Rat).SetInt64(2)

	for i := 0; i < limit; i++ {
		temp := new(big.Rat)
		tail.Add(two, temp.Inv(tail))   // tail = (2 + 1/tail)
		result.Add(one, temp.Inv(tail)) // result = (1 + 1/tail)
		if checkNumerator(result) {
			sum++
		}
	}
	return sum
}
コード例 #26
0
ファイル: libofx.go プロジェクト: aclindsa/moneygo
//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
}
コード例 #27
0
ファイル: exact.go プロジェクト: Bosh-for-Cpi/bosh-2605
// 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))
}
コード例 #28
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
}
コード例 #29
0
ファイル: evaler.go プロジェクト: sguzwf/algorithm
// 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
}
コード例 #30
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
}