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