github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/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 string-to-Float conversion functions. 6 7 package big 8 9 import ( 10 "fmt" 11 "io" 12 "strings" 13 ) 14 15 // SetString sets z to the value of s and returns z and a boolean indicating 16 // success. s must be a floating-point number of the same format as accepted 17 // by Parse, with base argument 0. 18 func (z *Float) SetString(s string) (*Float, bool) { 19 if f, _, err := z.Parse(s, 0); err == nil { 20 return f, true 21 } 22 return nil, false 23 } 24 25 // scan is like Parse but reads the longest possible prefix representing a valid 26 // floating point number from an io.ByteScanner rather than a string. It serves 27 // as the implementation of Parse. It does not recognize ±Inf and does not expect 28 // EOF at the end. 29 func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) { 30 prec := z.prec 31 if prec == 0 { 32 prec = 64 33 } 34 35 // A reasonable value in case of an error. 36 z.form = zero 37 38 // sign 39 z.neg, err = scanSign(r) 40 if err != nil { 41 return 42 } 43 44 // mantissa 45 var fcount int // fractional digit count; valid if <= 0 46 z.mant, b, fcount, err = z.mant.scan(r, base, true) 47 if err != nil { 48 return 49 } 50 51 // exponent 52 var exp int64 53 var ebase int 54 exp, ebase, err = scanExponent(r, true) 55 if err != nil { 56 return 57 } 58 59 // special-case 0 60 if len(z.mant) == 0 { 61 z.prec = prec 62 z.acc = Exact 63 z.form = zero 64 f = z 65 return 66 } 67 // len(z.mant) > 0 68 69 // The mantissa may have a decimal point (fcount <= 0) and there 70 // may be a nonzero exponent exp. The decimal point amounts to a 71 // division by b**(-fcount). An exponent means multiplication by 72 // ebase**exp. Finally, mantissa normalization (shift left) requires 73 // a correcting multiplication by 2**(-shiftcount). Multiplications 74 // are commutative, so we can apply them in any order as long as there 75 // is no loss of precision. We only have powers of 2 and 10, and 76 // we split powers of 10 into the product of the same powers of 77 // 2 and 5. This reduces the size of the multiplication factor 78 // needed for base-10 exponents. 79 80 // normalize mantissa and determine initial exponent contributions 81 exp2 := int64(len(z.mant))*_W - fnorm(z.mant) 82 exp5 := int64(0) 83 84 // determine binary or decimal exponent contribution of decimal point 85 if fcount < 0 { 86 // The mantissa has a "decimal" point ddd.dddd; and 87 // -fcount is the number of digits to the right of '.'. 88 // Adjust relevant exponent accodingly. 89 d := int64(fcount) 90 switch b { 91 case 10: 92 exp5 = d 93 fallthrough // 10**e == 5**e * 2**e 94 case 2: 95 exp2 += d 96 case 16: 97 exp2 += d * 4 // hexadecimal digits are 4 bits each 98 default: 99 panic("unexpected mantissa base") 100 } 101 // fcount consumed - not needed anymore 102 } 103 104 // take actual exponent into account 105 switch ebase { 106 case 10: 107 exp5 += exp 108 fallthrough 109 case 2: 110 exp2 += exp 111 default: 112 panic("unexpected exponent base") 113 } 114 // exp consumed - not needed anymore 115 116 // apply 2**exp2 117 if MinExp <= exp2 && exp2 <= MaxExp { 118 z.prec = prec 119 z.form = finite 120 z.exp = int32(exp2) 121 f = z 122 } else { 123 err = fmt.Errorf("exponent overflow") 124 return 125 } 126 127 if exp5 == 0 { 128 // no decimal exponent contribution 129 z.round(0) 130 return 131 } 132 // exp5 != 0 133 134 // apply 5**exp5 135 p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number? 136 if exp5 < 0 { 137 z.Quo(z, p.pow5(uint64(-exp5))) 138 } else { 139 z.Mul(z, p.pow5(uint64(exp5))) 140 } 141 142 return 143 } 144 145 // These powers of 5 fit into a uint64. 146 // 147 // for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 { 148 // fmt.Println(q) 149 // } 150 // 151 var pow5tab = [...]uint64{ 152 1, 153 5, 154 25, 155 125, 156 625, 157 3125, 158 15625, 159 78125, 160 390625, 161 1953125, 162 9765625, 163 48828125, 164 244140625, 165 1220703125, 166 6103515625, 167 30517578125, 168 152587890625, 169 762939453125, 170 3814697265625, 171 19073486328125, 172 95367431640625, 173 476837158203125, 174 2384185791015625, 175 11920928955078125, 176 59604644775390625, 177 298023223876953125, 178 1490116119384765625, 179 7450580596923828125, 180 } 181 182 // pow5 sets z to 5**n and returns z. 183 // n must not be negative. 184 func (z *Float) pow5(n uint64) *Float { 185 const m = uint64(len(pow5tab) - 1) 186 if n <= m { 187 return z.SetUint64(pow5tab[n]) 188 } 189 // n > m 190 191 z.SetUint64(pow5tab[m]) 192 n -= m 193 194 // use more bits for f than for z 195 // TODO(gri) what is the right number? 196 f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5) 197 198 for n > 0 { 199 if n&1 != 0 { 200 z.Mul(z, f) 201 } 202 f.Mul(f, f) 203 n >>= 1 204 } 205 206 return z 207 } 208 209 // Parse parses s which must contain a text representation of a floating- 210 // point number with a mantissa in the given conversion base (the exponent 211 // is always a decimal number), or a string representing an infinite value. 212 // 213 // It sets z to the (possibly rounded) value of the corresponding floating- 214 // point value, and returns z, the actual base b, and an error err, if any. 215 // If z's precision is 0, it is changed to 64 before rounding takes effect. 216 // The number must be of the form: 217 // 218 // number = [ sign ] [ prefix ] mantissa [ exponent ] | infinity . 219 // sign = "+" | "-" . 220 // prefix = "0" ( "x" | "X" | "b" | "B" ) . 221 // mantissa = digits | digits "." [ digits ] | "." digits . 222 // exponent = ( "E" | "e" | "p" ) [ sign ] digits . 223 // digits = digit { digit } . 224 // digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" . 225 // infinity = [ sign ] ( "inf" | "Inf" ) . 226 // 227 // The base argument must be 0, 2, 10, or 16. Providing an invalid base 228 // argument will lead to a run-time panic. 229 // 230 // For base 0, the number prefix determines the actual base: A prefix of 231 // "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects 232 // base 2; otherwise, the actual base is 10 and no prefix is accepted. 233 // The octal prefix "0" is not supported (a leading "0" is simply 234 // considered a "0"). 235 // 236 // A "p" exponent indicates a binary (rather then decimal) exponent; 237 // for instance "0x1.fffffffffffffp1023" (using base 0) represents the 238 // maximum float64 value. For hexadecimal mantissae, the exponent must 239 // be binary, if present (an "e" or "E" exponent indicator cannot be 240 // distinguished from a mantissa digit). 241 // 242 // The returned *Float f is nil and the value of z is valid but not 243 // defined if an error is reported. 244 // 245 func (z *Float) Parse(s string, base int) (f *Float, b int, err error) { 246 // scan doesn't handle ±Inf 247 if len(s) == 3 && (s == "Inf" || s == "inf") { 248 f = z.SetInf(false) 249 return 250 } 251 if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") { 252 f = z.SetInf(s[0] == '-') 253 return 254 } 255 256 r := strings.NewReader(s) 257 if f, b, err = z.scan(r, base); err != nil { 258 return 259 } 260 261 // entire string must have been consumed 262 if ch, err2 := r.ReadByte(); err2 == nil { 263 err = fmt.Errorf("expected end of string, found %q", ch) 264 } else if err2 != io.EOF { 265 err = err2 266 } 267 268 return 269 } 270 271 // ParseFloat is like f.Parse(s, base) with f set to the given precision 272 // and rounding mode. 273 func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) { 274 return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base) 275 }