// 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), } }
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 }
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 }
// 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) }
func newF(conf *config.Config) *big.Float { return new(big.Float).SetPrec(conf.FloatPrec()) }
func bigFloatInt64(conf *config.Config, x int64) BigFloat { return BigFloat{new(big.Float).SetPrec(conf.FloatPrec()).SetInt64(x)} }