/big/rat.go

https://code.google.com/p/algogo/ · Go · 371 lines · 267 code · 44 blank · 60 comment · 48 complexity · 7bce3e25a89f6bfdff156dcd9f748b05 MD5 · raw file

  1. // Copyright 2010 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 multi-precision rational numbers.
  5. package big
  6. import (
  7. "encoding/binary"
  8. "fmt"
  9. "os"
  10. "strings"
  11. )
  12. // A Rat represents a quotient a/b of arbitrary precision. The zero value for
  13. // a Rat, 0/0, is not a legal Rat.
  14. type Rat struct {
  15. a Int
  16. b nat
  17. }
  18. // NewRat creates a new Rat with numerator a and denominator b.
  19. func NewRat(a, b int64) *Rat {
  20. return new(Rat).SetFrac64(a, b)
  21. }
  22. // SetFrac sets z to a/b and returns z.
  23. func (z *Rat) SetFrac(a, b *Int) *Rat {
  24. z.a.Set(a)
  25. z.a.neg = a.neg != b.neg
  26. z.b = z.b.set(b.abs)
  27. return z.norm()
  28. }
  29. // SetFrac64 sets z to a/b and returns z.
  30. func (z *Rat) SetFrac64(a, b int64) *Rat {
  31. z.a.SetInt64(a)
  32. if b < 0 {
  33. b = -b
  34. z.a.neg = !z.a.neg
  35. }
  36. z.b = z.b.setUint64(uint64(b))
  37. return z.norm()
  38. }
  39. // SetInt sets z to x (by making a copy of x) and returns z.
  40. func (z *Rat) SetInt(x *Int) *Rat {
  41. z.a.Set(x)
  42. z.b = z.b.setWord(1)
  43. return z
  44. }
  45. // SetInt64 sets z to x and returns z.
  46. func (z *Rat) SetInt64(x int64) *Rat {
  47. z.a.SetInt64(x)
  48. z.b = z.b.setWord(1)
  49. return z
  50. }
  51. // Sign returns:
  52. //
  53. // -1 if x < 0
  54. // 0 if x == 0
  55. // +1 if x > 0
  56. //
  57. func (x *Rat) Sign() int {
  58. return x.a.Sign()
  59. }
  60. // IsInt returns true if the denominator of x is 1.
  61. func (x *Rat) IsInt() bool {
  62. return len(x.b) == 1 && x.b[0] == 1
  63. }
  64. // Num returns the numerator of z; it may be <= 0.
  65. // The result is a reference to z's numerator; it
  66. // may change if a new value is assigned to z.
  67. func (z *Rat) Num() *Int {
  68. return &z.a
  69. }
  70. // Denom returns the denominator of z; it is always > 0.
  71. // The result is a reference to z's denominator; it
  72. // may change if a new value is assigned to z.
  73. func (z *Rat) Denom() *Int {
  74. return &Int{false, z.b}
  75. }
  76. func gcd(x, y nat) nat {
  77. // Euclidean algorithm.
  78. var a, b nat
  79. a = a.set(x)
  80. b = b.set(y)
  81. for len(b) != 0 {
  82. var q, r nat
  83. _, r = q.div(r, a, b)
  84. a = b
  85. b = r
  86. }
  87. return a
  88. }
  89. func (z *Rat) norm() *Rat {
  90. f := gcd(z.a.abs, z.b)
  91. if len(z.a.abs) == 0 {
  92. // z == 0
  93. z.a.neg = false // normalize sign
  94. z.b = z.b.setWord(1)
  95. return z
  96. }
  97. if f.cmp(natOne) != 0 {
  98. z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f)
  99. z.b, _ = z.b.div(nil, z.b, f)
  100. }
  101. return z
  102. }
  103. func mulNat(x *Int, y nat) *Int {
  104. var z Int
  105. z.abs = z.abs.mul(x.abs, y)
  106. z.neg = len(z.abs) > 0 && x.neg
  107. return &z
  108. }
  109. // Cmp compares x and y and returns:
  110. //
  111. // -1 if x < y
  112. // 0 if x == y
  113. // +1 if x > y
  114. //
  115. func (x *Rat) Cmp(y *Rat) (r int) {
  116. return mulNat(&x.a, y.b).Cmp(mulNat(&y.a, x.b))
  117. }
  118. // Abs sets z to |x| (the absolute value of x) and returns z.
  119. func (z *Rat) Abs(x *Rat) *Rat {
  120. z.a.Abs(&x.a)
  121. z.b = z.b.set(x.b)
  122. return z
  123. }
  124. // Add sets z to the sum x+y and returns z.
  125. func (z *Rat) Add(x, y *Rat) *Rat {
  126. a1 := mulNat(&x.a, y.b)
  127. a2 := mulNat(&y.a, x.b)
  128. z.a.Add(a1, a2)
  129. z.b = z.b.mul(x.b, y.b)
  130. return z.norm()
  131. }
  132. // Sub sets z to the difference x-y and returns z.
  133. func (z *Rat) Sub(x, y *Rat) *Rat {
  134. a1 := mulNat(&x.a, y.b)
  135. a2 := mulNat(&y.a, x.b)
  136. z.a.Sub(a1, a2)
  137. z.b = z.b.mul(x.b, y.b)
  138. return z.norm()
  139. }
  140. // Mul sets z to the product x*y and returns z.
  141. func (z *Rat) Mul(x, y *Rat) *Rat {
  142. z.a.Mul(&x.a, &y.a)
  143. z.b = z.b.mul(x.b, y.b)
  144. return z.norm()
  145. }
  146. // Quo sets z to the quotient x/y and returns z.
  147. // If y == 0, a division-by-zero run-time panic occurs.
  148. func (z *Rat) Quo(x, y *Rat) *Rat {
  149. if len(y.a.abs) == 0 {
  150. panic("division by zero")
  151. }
  152. a := mulNat(&x.a, y.b)
  153. b := mulNat(&y.a, x.b)
  154. z.a.abs = a.abs
  155. z.b = b.abs
  156. z.a.neg = a.neg != b.neg
  157. return z.norm()
  158. }
  159. // Neg sets z to -x (by making a copy of x if necessary) and returns z.
  160. func (z *Rat) Neg(x *Rat) *Rat {
  161. z.a.Neg(&x.a)
  162. z.b = z.b.set(x.b)
  163. return z
  164. }
  165. // Set sets z to x (by making a copy of x if necessary) and returns z.
  166. func (z *Rat) Set(x *Rat) *Rat {
  167. z.a.Set(&x.a)
  168. z.b = z.b.set(x.b)
  169. return z
  170. }
  171. func ratTok(ch int) bool {
  172. return strings.IndexRune("+-/0123456789.eE", ch) >= 0
  173. }
  174. // Scan is a support routine for fmt.Scanner. It accepts the formats
  175. // 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
  176. func (z *Rat) Scan(s fmt.ScanState, ch int) os.Error {
  177. tok, err := s.Token(true, ratTok)
  178. if err != nil {
  179. return err
  180. }
  181. if strings.IndexRune("efgEFGv", ch) < 0 {
  182. return os.NewError("Rat.Scan: invalid verb")
  183. }
  184. if _, ok := z.SetString(string(tok)); !ok {
  185. return os.NewError("Rat.Scan: invalid syntax")
  186. }
  187. return nil
  188. }
  189. // SetString sets z to the value of s and returns z and a boolean indicating
  190. // success. s can be given as a fraction "a/b" or as a floating-point number
  191. // optionally followed by an exponent. If the operation failed, the value of z
  192. // is undefined.
  193. func (z *Rat) SetString(s string) (*Rat, bool) {
  194. if len(s) == 0 {
  195. return z, false
  196. }
  197. // check for a quotient
  198. sep := strings.Index(s, "/")
  199. if sep >= 0 {
  200. if _, ok := z.a.SetString(s[0:sep], 10); !ok {
  201. return z, false
  202. }
  203. s = s[sep+1:]
  204. var err os.Error
  205. if z.b, _, err = z.b.scan(strings.NewReader(s), 10); err != nil {
  206. return z, false
  207. }
  208. return z.norm(), true
  209. }
  210. // check for a decimal point
  211. sep = strings.Index(s, ".")
  212. // check for an exponent
  213. e := strings.IndexAny(s, "eE")
  214. var exp Int
  215. if e >= 0 {
  216. if e < sep {
  217. // The E must come after the decimal point.
  218. return z, false
  219. }
  220. if _, ok := exp.SetString(s[e+1:], 10); !ok {
  221. return z, false
  222. }
  223. s = s[0:e]
  224. }
  225. if sep >= 0 {
  226. s = s[0:sep] + s[sep+1:]
  227. exp.Sub(&exp, NewInt(int64(len(s)-sep)))
  228. }
  229. if _, ok := z.a.SetString(s, 10); !ok {
  230. return z, false
  231. }
  232. powTen := nat{}.expNN(natTen, exp.abs, nil)
  233. if exp.neg {
  234. z.b = powTen
  235. z.norm()
  236. } else {
  237. z.a.abs = z.a.abs.mul(z.a.abs, powTen)
  238. z.b = z.b.setWord(1)
  239. }
  240. return z, true
  241. }
  242. // String returns a string representation of z in the form "a/b" (even if b == 1).
  243. func (z *Rat) String() string {
  244. return z.a.String() + "/" + z.b.decimalString()
  245. }
  246. // RatString returns a string representation of z in the form "a/b" if b != 1,
  247. // and in the form "a" if b == 1.
  248. func (z *Rat) RatString() string {
  249. if z.IsInt() {
  250. return z.a.String()
  251. }
  252. return z.String()
  253. }
  254. // FloatString returns a string representation of z in decimal form with prec
  255. // digits of precision after the decimal point and the last digit rounded.
  256. func (z *Rat) FloatString(prec int) string {
  257. if z.IsInt() {
  258. s := z.a.String()
  259. if prec > 0 {
  260. s += "." + strings.Repeat("0", prec)
  261. }
  262. return s
  263. }
  264. q, r := nat{}.div(nat{}, z.a.abs, z.b)
  265. p := natOne
  266. if prec > 0 {
  267. p = nat{}.expNN(natTen, nat{}.setUint64(uint64(prec)), nil)
  268. }
  269. r = r.mul(r, p)
  270. r, r2 := r.div(nat{}, r, z.b)
  271. // see if we need to round up
  272. r2 = r2.add(r2, r2)
  273. if z.b.cmp(r2) <= 0 {
  274. r = r.add(r, natOne)
  275. if r.cmp(p) >= 0 {
  276. q = nat{}.add(q, natOne)
  277. r = nat{}.sub(r, p)
  278. }
  279. }
  280. s := q.decimalString()
  281. if z.a.neg {
  282. s = "-" + s
  283. }
  284. if prec > 0 {
  285. rs := r.decimalString()
  286. leadingZeros := prec - len(rs)
  287. s += "." + strings.Repeat("0", leadingZeros) + rs
  288. }
  289. return s
  290. }
  291. // Gob codec version. Permits backward-compatible changes to the encoding.
  292. const ratGobVersion byte = 1
  293. // GobEncode implements the gob.GobEncoder interface.
  294. func (z *Rat) GobEncode() ([]byte, os.Error) {
  295. buf := make([]byte, 1+4+(len(z.a.abs)+len(z.b))*_S) // extra bytes for version and sign bit (1), and numerator length (4)
  296. i := z.b.bytes(buf)
  297. j := z.a.abs.bytes(buf[0:i])
  298. n := i - j
  299. if int(uint32(n)) != n {
  300. // this should never happen
  301. return nil, os.NewError("Rat.GobEncode: numerator too large")
  302. }
  303. binary.BigEndian.PutUint32(buf[j-4:j], uint32(n))
  304. j -= 1 + 4
  305. b := ratGobVersion << 1 // make space for sign bit
  306. if z.a.neg {
  307. b |= 1
  308. }
  309. buf[j] = b
  310. return buf[j:], nil
  311. }
  312. // GobDecode implements the gob.GobDecoder interface.
  313. func (z *Rat) GobDecode(buf []byte) os.Error {
  314. if len(buf) == 0 {
  315. return os.NewError("Rat.GobDecode: no data")
  316. }
  317. b := buf[0]
  318. if b>>1 != ratGobVersion {
  319. return os.NewError(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1))
  320. }
  321. const j = 1 + 4
  322. i := j + binary.BigEndian.Uint32(buf[j-4:j])
  323. z.a.neg = b&1 != 0
  324. z.a.abs = z.a.abs.setBytes(buf[j:i])
  325. z.b = z.b.setBytes(buf[i:])
  326. return nil
  327. }