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 "" }
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)) }
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) }
// 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 (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) }