github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/math/big/floatconv.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements float-to-string conversion functions. 6 7 package big 8 9 import ( 10 "fmt" 11 "io" 12 "strconv" 13 "strings" 14 ) 15 16 // SetString sets z to the value of s and returns z and a boolean indicating 17 // success. s must be a floating-point number of the same format as accepted 18 // by Scan, with number prefixes permitted. 19 func (z *Float) SetString(s string) (*Float, bool) { 20 r := strings.NewReader(s) 21 22 f, _, err := z.Scan(r, 0) 23 if err != nil { 24 return nil, false 25 } 26 27 // there should be no unread characters left 28 if _, err = r.ReadByte(); err != io.EOF { 29 return nil, false 30 } 31 32 return f, true 33 } 34 35 // Scan scans the number corresponding to the longest possible prefix 36 // of r representing a floating-point number with a mantissa in the 37 // given conversion base (the exponent is always a decimal number). 38 // It sets z to the (possibly rounded) value of the corresponding 39 // floating-point number, and returns z, the actual base b, and an 40 // error err, if any. If z's precision is 0, it is changed to 64 41 // before rounding takes effect. The number must be of the form: 42 // 43 // number = [ sign ] [ prefix ] mantissa [ exponent ] . 44 // sign = "+" | "-" . 45 // prefix = "0" ( "x" | "X" | "b" | "B" ) . 46 // mantissa = digits | digits "." [ digits ] | "." digits . 47 // exponent = ( "E" | "e" | "p" ) [ sign ] digits . 48 // digits = digit { digit } . 49 // digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" . 50 // 51 // The base argument must be 0, 2, 10, or 16. Providing an invalid base 52 // argument will lead to a run-time panic. 53 // 54 // For base 0, the number prefix determines the actual base: A prefix of 55 // "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects 56 // base 2; otherwise, the actual base is 10 and no prefix is accepted. 57 // The octal prefix "0" is not supported (a leading "0" is simply 58 // considered a "0"). 59 // 60 // A "p" exponent indicates a binary (rather then decimal) exponent; 61 // for instance "0x1.fffffffffffffp1023" (using base 0) represents the 62 // maximum float64 value. For hexadecimal mantissae, the exponent must 63 // be binary, if present (an "e" or "E" exponent indicator cannot be 64 // distinguished from a mantissa digit). 65 // 66 // The returned *Float f is nil and the value of z is valid but not 67 // defined if an error is reported. 68 // 69 // BUG(gri) The Float.Scan signature conflicts with Scan(s fmt.ScanState, ch rune) error. 70 func (z *Float) Scan(r io.ByteScanner, base int) (f *Float, b int, err error) { 71 prec := z.prec 72 if prec == 0 { 73 prec = 64 74 } 75 76 // A reasonable value in case of an error. 77 z.form = zero 78 79 // sign 80 z.neg, err = scanSign(r) 81 if err != nil { 82 return 83 } 84 85 // mantissa 86 var fcount int // fractional digit count; valid if <= 0 87 z.mant, b, fcount, err = z.mant.scan(r, base, true) 88 if err != nil { 89 return 90 } 91 92 // exponent 93 var exp int64 94 var ebase int 95 exp, ebase, err = scanExponent(r, true) 96 if err != nil { 97 return 98 } 99 100 // special-case 0 101 if len(z.mant) == 0 { 102 z.prec = prec 103 z.acc = Exact 104 z.form = zero 105 f = z 106 return 107 } 108 // len(z.mant) > 0 109 110 // The mantissa may have a decimal point (fcount <= 0) and there 111 // may be a nonzero exponent exp. The decimal point amounts to a 112 // division by b**(-fcount). An exponent means multiplication by 113 // ebase**exp. Finally, mantissa normalization (shift left) requires 114 // a correcting multiplication by 2**(-shiftcount). Multiplications 115 // are commutative, so we can apply them in any order as long as there 116 // is no loss of precision. We only have powers of 2 and 10; keep 117 // track via separate exponents exp2 and exp10. 118 119 // normalize mantissa and get initial binary exponent 120 var exp2 = int64(len(z.mant))*_W - fnorm(z.mant) 121 122 // determine binary or decimal exponent contribution of decimal point 123 var exp10 int64 124 if fcount < 0 { 125 // The mantissa has a "decimal" point ddd.dddd; and 126 // -fcount is the number of digits to the right of '.'. 127 // Adjust relevant exponent accodingly. 128 switch b { 129 case 16: 130 fcount *= 4 // hexadecimal digits are 4 bits each 131 fallthrough 132 case 2: 133 exp2 += int64(fcount) 134 default: // b == 10 135 exp10 = int64(fcount) 136 } 137 // we don't need fcount anymore 138 } 139 140 // take actual exponent into account 141 if ebase == 2 { 142 exp2 += exp 143 } else { // ebase == 10 144 exp10 += exp 145 } 146 // we don't need exp anymore 147 148 // apply 2**exp2 149 if MinExp <= exp2 && exp2 <= MaxExp { 150 z.prec = prec 151 z.form = finite 152 z.exp = int32(exp2) 153 f = z 154 } else { 155 err = fmt.Errorf("exponent overflow") 156 return 157 } 158 159 if exp10 == 0 { 160 // no decimal exponent to consider 161 z.round(0) 162 return 163 } 164 // exp10 != 0 165 166 // apply 10**exp10 167 p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number? 168 if exp10 < 0 { 169 z.uquo(z, p.pow10(-exp10)) 170 } else { 171 z.umul(z, p.pow10(exp10)) 172 } 173 174 return 175 } 176 177 // These powers of 10 can be represented exactly as a float64. 178 var pow10tab = [...]float64{ 179 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 180 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 181 } 182 183 // pow10 sets z to 10**n and returns z. 184 // n must not be negative. 185 func (z *Float) pow10(n int64) *Float { 186 if n < 0 { 187 panic("pow10 called with negative argument") 188 } 189 190 const m = int64(len(pow10tab) - 1) 191 if n <= m { 192 return z.SetFloat64(pow10tab[n]) 193 } 194 // n > m 195 196 z.SetFloat64(pow10tab[m]) 197 n -= m 198 199 // use more bits for f than for z 200 // TODO(gri) what is the right number? 201 f := new(Float).SetPrec(z.Prec() + 64).SetInt64(10) 202 203 for n > 0 { 204 if n&1 != 0 { 205 z.Mul(z, f) 206 } 207 f.Mul(f, f) 208 n >>= 1 209 } 210 211 return z 212 } 213 214 // Parse is like z.Scan(r, base), but instead of reading from an 215 // io.ByteScanner, it parses the string s. An error is also returned 216 // if the string contains invalid or trailing bytes not belonging to 217 // the number. 218 func (z *Float) Parse(s string, base int) (f *Float, b int, err error) { 219 r := strings.NewReader(s) 220 221 if f, b, err = z.Scan(r, base); err != nil { 222 return 223 } 224 225 // entire string must have been consumed 226 if ch, err2 := r.ReadByte(); err2 == nil { 227 err = fmt.Errorf("expected end of string, found %q", ch) 228 } else if err2 != io.EOF { 229 err = err2 230 } 231 232 return 233 } 234 235 // ScanFloat is like f.Scan(r, base) with f set to the given precision 236 // and rounding mode. 237 func ScanFloat(r io.ByteScanner, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) { 238 return new(Float).SetPrec(prec).SetMode(mode).Scan(r, base) 239 } 240 241 // ParseFloat is like f.Parse(s, base) with f set to the given precision 242 // and rounding mode. 243 func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) { 244 return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base) 245 } 246 247 // Format converts the floating-point number x to a string according 248 // to the given format and precision prec. The format is one of: 249 // 250 // 'e' -d.dddde±dd, decimal exponent, at least two (possibly 0) exponent digits 251 // 'E' -d.ddddE±dd, decimal exponent, at least two (possibly 0) exponent digits 252 // 'f' -ddddd.dddd, no exponent 253 // 'g' like 'e' for large exponents, like 'f' otherwise 254 // 'G' like 'E' for large exponents, like 'f' otherwise 255 // 'b' -ddddddp±dd, binary exponent 256 // 'p' -0x.dddp±dd, binary exponent, hexadecimal mantissa 257 // 258 // For the binary exponent formats, the mantissa is printed in normalized form: 259 // 260 // 'b' decimal integer mantissa using x.Prec() bits, or -0 261 // 'p' hexadecimal fraction with 0.5 <= 0.mantissa < 1.0, or -0 262 // 263 // The precision prec controls the number of digits (excluding the exponent) 264 // printed by the 'e', 'E', 'f', 'g', and 'G' formats. For 'e', 'E', and 'f' 265 // it is the number of digits after the decimal point. For 'g' and 'G' it is 266 // the total number of digits. A negative precision selects the smallest 267 // number of digits necessary such that ParseFloat will return f exactly. 268 // The prec value is ignored for the 'b' or 'p' format. 269 // 270 // BUG(gri) Float.Format does not accept negative precisions. 271 func (x *Float) Format(format byte, prec int) string { 272 const extra = 10 // TODO(gri) determine a good/better value here 273 return string(x.Append(make([]byte, 0, prec+extra), format, prec)) 274 } 275 276 // Append appends the string form of the floating-point number x, 277 // as generated by x.Format, to buf and returns the extended buffer. 278 func (x *Float) Append(buf []byte, format byte, prec int) []byte { 279 // TODO(gri) factor out handling of sign? 280 281 // Inf 282 if x.IsInf() { 283 var ch byte = '+' 284 if x.neg { 285 ch = '-' 286 } 287 buf = append(buf, ch) 288 return append(buf, "Inf"...) 289 } 290 291 // easy formats 292 switch format { 293 case 'b': 294 return x.bstring(buf) 295 case 'p': 296 return x.pstring(buf) 297 } 298 299 return x.bigFtoa(buf, format, prec) 300 } 301 302 // BUG(gri): Float.String uses x.Format('g', 10) rather than x.Format('g', -1). 303 func (x *Float) String() string { 304 return x.Format('g', 10) 305 } 306 307 // bstring appends the string of x in the format ["-"] mantissa "p" exponent 308 // with a decimal mantissa and a binary exponent, or ["-"] "0" if x is zero, 309 // and returns the extended buffer. 310 // The mantissa is normalized such that is uses x.Prec() bits in binary 311 // representation. 312 func (x *Float) bstring(buf []byte) []byte { 313 if x.neg { 314 buf = append(buf, '-') 315 } 316 if x.form == zero { 317 return append(buf, '0') 318 } 319 320 if debugFloat && x.form != finite { 321 panic("non-finite float") 322 } 323 // x != 0 324 325 // adjust mantissa to use exactly x.prec bits 326 m := x.mant 327 switch w := uint32(len(x.mant)) * _W; { 328 case w < x.prec: 329 m = nat(nil).shl(m, uint(x.prec-w)) 330 case w > x.prec: 331 m = nat(nil).shr(m, uint(w-x.prec)) 332 } 333 334 buf = append(buf, m.decimalString()...) 335 buf = append(buf, 'p') 336 e := int64(x.exp) - int64(x.prec) 337 if e >= 0 { 338 buf = append(buf, '+') 339 } 340 return strconv.AppendInt(buf, e, 10) 341 } 342 343 // pstring appends the string of x in the format ["-"] "0x." mantissa "p" exponent 344 // with a hexadecimal mantissa and a binary exponent, or ["-"] "0" if x is zero, 345 // ad returns the extended buffer. 346 // The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0. 347 func (x *Float) pstring(buf []byte) []byte { 348 if x.neg { 349 buf = append(buf, '-') 350 } 351 if x.form == zero { 352 return append(buf, '0') 353 } 354 355 if debugFloat && x.form != finite { 356 panic("non-finite float") 357 } 358 // x != 0 359 360 // remove trailing 0 words early 361 // (no need to convert to hex 0's and trim later) 362 m := x.mant 363 i := 0 364 for i < len(m) && m[i] == 0 { 365 i++ 366 } 367 m = m[i:] 368 369 buf = append(buf, "0x."...) 370 buf = append(buf, strings.TrimRight(x.mant.hexString(), "0")...) 371 buf = append(buf, 'p') 372 return strconv.AppendInt(buf, int64(x.exp), 10) 373 }