github.com/elves/elvish@v0.15.0/pkg/eval/vals/string.go (about) 1 package vals 2 3 import ( 4 "strconv" 5 "strings" 6 ) 7 8 // Stringer wraps the String method. 9 type Stringer interface { 10 // Stringer converts the receiver to a string. 11 String() string 12 } 13 14 // ToString converts a Value to string. It is implemented for the builtin 15 // float64 and string types, and type satisfying the Stringer interface. It 16 // falls back to Repr(v, NoPretty). 17 func ToString(v interface{}) string { 18 switch v := v.(type) { 19 case float64: 20 return formatFloat64(v) 21 case string: 22 return v 23 case Stringer: 24 return v.String() 25 default: 26 return Repr(v, NoPretty) 27 } 28 } 29 30 func formatFloat64(f float64) string { 31 // Go's 'g' format is not quite ideal for printing floating point numbers; 32 // it uses scientific notation too aggressively, and relatively small 33 // numbers like 1234567 are printed with scientific notations, something we 34 // don't really want. 35 // 36 // So we use a different algorithm for determining when to use scientific 37 // notation. The algorithm is reverse-engineered from Racket's; it may not 38 // be a perfect clone but hopefully good enough. 39 // 40 // See also b.elv.sh/811 for more context. 41 s := strconv.FormatFloat(f, 'f', -1, 64) 42 if (strings.IndexByte(s, '.') == -1 && len(s) > 14 && s[len(s)-1] == '0') || 43 strings.HasPrefix(s, "0.0000") { 44 return strconv.FormatFloat(f, 'e', -1, 64) 45 } 46 return s 47 }