floatconv.go 8.4 KB

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