コード例 #1
0
ファイル: bigint.go プロジェクト: ghost-dog/ivy
func setBigIntString(conf *config.Config, s string) (BigInt, error) {
	i, ok := big.NewInt(0).SetString(s, conf.InputBase())
	if !ok {
		return BigInt{}, errors.New("integer parse error")
	}
	return BigInt{i}, nil
}
コード例 #2
0
ファイル: run.go プロジェクト: db47h/ivy
// printValues neatly prints the values returned from execution, followed by a newline.
// It also handles the ')debug types' output.
// The return value reports whether it printed anything.
func printValues(conf *config.Config, writer io.Writer, values []value.Value) bool {
	if len(values) == 0 {
		return false
	}
	if conf.Debug("types") {
		for i, v := range values {
			if i > 0 {
				fmt.Fprint(writer, ",")
			}
			fmt.Fprintf(writer, "%T", v)
		}
		fmt.Fprintln(writer)
	}
	printed := false
	for _, v := range values {
		if _, ok := v.(parse.Assignment); ok {
			continue
		}
		s := v.Sprint(conf)
		if printed && len(s) > 0 && s[len(s)-1] != '\n' {
			fmt.Fprint(writer, " ")
		}
		fmt.Fprint(writer, s)
		printed = true
	}
	if printed {
		fmt.Fprintln(writer)
	}
	return printed
}
コード例 #3
0
ファイル: bigint.go プロジェクト: ghost-dog/ivy
func (i BigInt) Sprint(conf *config.Config) string {
	bitLen := i.BitLen()
	format := conf.Format()
	var maxBits = (uint64(conf.MaxDigits()) * 33222) / 10000 // log 10 / log 2 is 3.32192809489
	if uint64(bitLen) > maxBits && maxBits != 0 {
		// Print in floating point.
		return BigFloat{newF(conf).SetInt(i.Int)}.Sprint(conf)
	}
	if format != "" {
		verb, prec, ok := conf.FloatFormat()
		if ok {
			return i.floatString(verb, prec)
		}
		return fmt.Sprintf(format, i.Int)
	}
	// Is this from a rational and we could use an int?
	if i.BitLen() < intBits {
		return Int(i.Int64()).Sprint(conf)
	}
	switch conf.OutputBase() {
	case 0, 10:
		return fmt.Sprintf("%d", i.Int)
	case 2:
		return fmt.Sprintf("%b", i.Int)
	case 8:
		return fmt.Sprintf("%o", i.Int)
	case 16:
		return fmt.Sprintf("%x", i.Int)
	}
	Errorf("can't print number in base %d (yet)", conf.OutputBase())
	return ""
}
コード例 #4
0
ファイル: loop.go プロジェクト: ghost-dog/ivy
// newLoop returns a new loop checker. The arguments are the name
// of the function being evaluated, the argument to the function, and
// the maximum number of iterations to perform before giving up.
// The last number in terms of iterations per bit, so the caller can
// ignore the precision setting.
func newLoop(conf *config.Config, name string, x *big.Float, itersPerBit uint) *loop {
	return &loop{
		name:          name,
		arg:           newF(conf).Set(x),
		maxIterations: 10 + uint64(itersPerBit*conf.FloatPrec()),
		prevZ:         newF(conf),
		delta:         newF(conf),
		prevDelta:     newF(conf),
	}
}
コード例 #5
0
ファイル: bigrat.go プロジェクト: ghost-dog/ivy
func (r BigRat) toType(conf *config.Config, which valueType) Value {
	switch which {
	case bigRatType:
		return r
	case bigFloatType:
		f := new(big.Float).SetPrec(conf.FloatPrec()).SetRat(r.Rat)
		return BigFloat{f}
	case vectorType:
		return NewVector([]Value{r})
	case matrixType:
		return NewMatrix([]Value{one, one}, []Value{r})
	}
	Errorf("cannot convert rational to %s", which)
	return nil
}
コード例 #6
0
ファイル: bigint.go プロジェクト: ghost-dog/ivy
func (i BigInt) toType(conf *config.Config, which valueType) Value {
	switch which {
	case bigIntType:
		return i
	case bigRatType:
		r := big.NewRat(0, 1).SetInt(i.Int)
		return BigRat{r}
	case bigFloatType:
		f := new(big.Float).SetPrec(conf.FloatPrec()).SetInt(i.Int)
		return BigFloat{f}
	case vectorType:
		return NewVector([]Value{i})
	case matrixType:
		return NewMatrix([]Value{one}, []Value{i})
	}
	Errorf("cannot convert big int to %s", which)
	return nil
}
コード例 #7
0
ファイル: matrix.go プロジェクト: ghost-dog/ivy
func (m Matrix) higherDim(conf *config.Config, prefix string, indentation int) string {
	if len(m.shape) <= 3 {
		return indent(indentation, m.Sprint(conf))
	}
	dim := int(m.shape[0].(Int))
	rest := strings.Repeat(" *", len(m.shape)-1)[1:]
	var b bytes.Buffer
	for i := 0; i < dim; i++ {
		inner := Matrix{
			shape: m.shape[1:],
			data:  m.data[i*m.elemSize():],
		}
		if i > 0 {
			b.WriteString("\n")
		}
		innerPrefix := fmt.Sprintf("%s%d ", prefix, i+conf.Origin())
		b.WriteString(indent(indentation, "%s%s]:\n", innerPrefix, rest))
		b.WriteString(inner.higherDim(conf, innerPrefix, indentation+1))
	}
	return b.String()
}
コード例 #8
0
ファイル: run.go プロジェクト: ghost-dog/ivy
// printValues neatly prints the values returned from execution, followed by a newline.
// It also handles the ')debug types' output.
func printValues(conf *config.Config, writer io.Writer, values []value.Value) {
	if len(values) == 0 {
		return
	}
	if conf.Debug("types") {
		for i, v := range values {
			if i > 0 {
				fmt.Fprint(writer, ",")
			}
			fmt.Fprintf(writer, "%T", v)
		}
		fmt.Fprintln(writer)
	}
	for i, v := range values {
		s := v.Sprint(conf)
		if i > 0 && len(s) > 0 && s[len(s)-1] != '\n' {
			fmt.Fprint(writer, " ")
		}
		fmt.Fprint(writer, s)
	}
	fmt.Fprintln(writer)
}
コード例 #9
0
ファイル: bigrat.go プロジェクト: ghost-dog/ivy
func (r BigRat) Sprint(conf *config.Config) string {
	format := conf.Format()
	if format != "" {
		verb, prec, ok := conf.FloatFormat()
		if ok {
			return r.floatString(verb, prec)
		}
		return fmt.Sprintf(conf.RatFormat(), r.Num(), r.Denom())
	}
	num := BigInt{r.Num()}
	den := BigInt{r.Denom()}
	return fmt.Sprintf("%s/%s", num.Sprint(conf), den.Sprint(conf))
}
コード例 #10
0
ファイル: int.go プロジェクト: ghost-dog/ivy
func (i Int) Sprint(conf *config.Config) string {
	format := conf.Format()
	if format != "" {
		verb, prec, ok := conf.FloatFormat()
		if ok {
			return i.floatString(verb, prec)
		}
		return fmt.Sprintf(format, int64(i))
	}
	base := conf.OutputBase()
	if base == 0 {
		base = 10
	}
	return strconv.FormatInt(int64(i), base)
}
コード例 #11
0
ファイル: int.go プロジェクト: ghost-dog/ivy
func setIntString(conf *config.Config, s string) (Int, error) {
	i, err := strconv.ParseInt(s, conf.InputBase(), intBits)
	return Int(i), err
}
コード例 #12
0
ファイル: save.go プロジェクト: zzn01/ivy
// save writes the state of the workspace to the named file.
// The format of the output is ivy source text.
func save(c *exec.Context, file string, conf *config.Config) {
	// "<conf.out>" is a special case for testing.
	out := conf.Output()
	if file != "<conf.out>" {
		fd, err := os.Create(file)
		if err != nil {
			value.Errorf("%s", err)
		}
		defer fd.Close()
		buf := bufio.NewWriter(fd)
		defer buf.Flush()
		out = buf
	}

	// Configuration settings. We will set the base below,
	// after we have printed all numbers in base 10.
	fmt.Fprintf(out, ")prec %d\n", conf.FloatPrec())
	ibase, obase := conf.Base()
	fmt.Fprintf(out, ")maxbits %d\n", conf.MaxBits())
	fmt.Fprintf(out, ")maxdigits %d\n", conf.MaxDigits())
	fmt.Fprintf(out, ")origin %d\n", conf.Origin())
	fmt.Fprintf(out, ")prompt %q\n", conf.Prompt())
	fmt.Fprintf(out, ")format %q\n", conf.Format())

	// Ops.
	printed := make(map[exec.OpDef]bool)
	for _, def := range c.Defs {
		var fn *exec.Function
		if def.IsBinary {
			fn = c.BinaryFn[def.Name]
		} else {
			fn = c.UnaryFn[def.Name]
		}
		for _, ref := range references(c, fn.Body) {
			if !printed[ref] {
				if ref.IsBinary {
					fmt.Fprintf(out, "op _ %s _\n", ref.Name)
				} else {
					fmt.Fprintf(out, "op %s _\n", ref.Name)
				}
				printed[ref] = true
			}
		}
		printed[def] = true
		fmt.Fprintln(out, fn)
	}

	// Global variables.
	syms := c.Stack[0]
	if len(syms) > 0 {
		// Set the base strictly to 10 for output.
		fmt.Fprintf(out, "# Set base 10 for parsing numbers.\n)base 10\n")
		// Sort the names for consistent output.
		sorted := sortSyms(syms)
		for _, sym := range sorted {
			// pi and e are generated
			if sym.name == "pi" || sym.name == "e" {
				continue
			}
			fmt.Fprintf(out, "%s = ", sym.name)
			put(out, sym.val)
			fmt.Fprint(out, "\n")
		}
	}

	// Now we can set the base.
	fmt.Fprintf(out, ")ibase %d\n", ibase)
	fmt.Fprintf(out, ")obase %d\n", obase)
}
コード例 #13
0
ファイル: const.go プロジェクト: ghost-dog/ivy
func newF(conf *config.Config) *big.Float {
	return new(big.Float).SetPrec(conf.FloatPrec())
}
コード例 #14
0
ファイル: value.go プロジェクト: ghost-dog/ivy
func bigFloatInt64(conf *config.Config, x int64) BigFloat {
	return BigFloat{new(big.Float).SetPrec(conf.FloatPrec()).SetInt64(x)}
}
コード例 #15
0
ファイル: bigfloat.go プロジェクト: ghost-dog/ivy
func (f BigFloat) Sprint(conf *config.Config) string {
	var mant big.Float
	exp := f.Float.MantExp(&mant)
	positive := 1
	if exp < 0 {
		positive = 0
		exp = -exp
	}
	verb, prec := byte('g'), 12
	format := conf.Format()
	if format != "" {
		v, p, ok := conf.FloatFormat()
		if ok {
			verb, prec = v, p
		}
	}
	// Printing huge floats can be very slow using
	// big.Float's native methods; see issue #11068.
	// For example 1e5000000 takes a minute of CPU time just
	// to print. The code below is instantaneous, by rescaling
	// first. It is however less feature-complete.
	// (Big ints are problematic too, but if you print 1e50000000
	// as an integer you probably won't be surprised it's slow.)

	if fastFloatPrint && exp > 10000 {
		// We always use %g to print the fraction, and it will
		// never have an exponent, but if the format is %E we
		// need to use a capital E.
		eChar := 'e'
		if verb == 'E' || verb == 'G' {
			eChar = 'E'
		}
		fexp := newF(conf).SetInt64(int64(exp))
		fexp.Mul(fexp, floatLog2)
		fexp.Quo(fexp, floatLog10)
		// We now have a floating-point base 10 exponent.
		// Break into the integer part and the fractional part.
		// The integer part is what we will show.
		// The 10**(fractional part) will be multiplied back in.
		iexp, _ := fexp.Int(nil)
		fraction := fexp.Sub(fexp, newF(conf).SetInt(iexp))
		// Now compute 10**(fractional part).
		// Fraction is in base 10. Move it to base e.
		fraction.Mul(fraction, floatLog10)
		scale := exponential(conf, fraction)
		if positive > 0 {
			mant.Mul(&mant, scale)
		} else {
			mant.Quo(&mant, scale)
		}
		ten := newF(conf).SetInt64(10)
		i64exp := iexp.Int64()
		// For numbers not too far from one, print without the E notation.
		// Shouldn't happen (exp must be large to get here) but just
		// in case, we keep this around.
		if -4 <= i64exp && i64exp <= 11 {
			if i64exp > 0 {
				for i := 0; i < int(i64exp); i++ {
					mant.Mul(&mant, ten)
				}
			} else {
				for i := 0; i < int(-i64exp); i++ {
					mant.Quo(&mant, ten)
				}
			}
			return fmt.Sprintf("%g\n", &mant)
		} else {
			sign := ""
			if mant.Sign() < 0 {
				sign = "-"
				mant.Neg(&mant)
			}
			// If it has a leading zero, rescale.
			digits := mant.Text('g', prec)
			for digits[0] == '0' {
				mant.Mul(&mant, ten)
				if positive > 0 {
					i64exp--
				} else {
					i64exp++
				}
				digits = mant.Text('g', prec)
			}
			return fmt.Sprintf("%s%s%c%c%d", sign, digits, eChar, "-+"[positive], i64exp)
		}
	}
	return f.Float.Text(verb, prec)
}
コード例 #16
0
ファイル: bigint.go プロジェクト: ghost-dog/ivy
// mustFit errors out if n is larger than the maximum number of bits allowed.
func mustFit(conf *config.Config, n int64) {
	max := conf.MaxBits()
	if max != 0 && n > int64(max) {
		Errorf("result too large (%d bits)", n)
	}
}