PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/math/big/rat_test.go

http://github.com/axw/llgo
Go | 736 lines | 616 code | 74 blank | 46 comment | 172 complexity | 739c0bed8566b3075948f36524389edc MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  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. package big
  5. import (
  6. "bytes"
  7. "encoding/gob"
  8. "encoding/json"
  9. "encoding/xml"
  10. "math"
  11. "testing"
  12. )
  13. func TestZeroRat(t *testing.T) {
  14. var x, y, z Rat
  15. y.SetFrac64(0, 42)
  16. if x.Cmp(&y) != 0 {
  17. t.Errorf("x and y should be both equal and zero")
  18. }
  19. if s := x.String(); s != "0/1" {
  20. t.Errorf("got x = %s, want 0/1", s)
  21. }
  22. if s := x.RatString(); s != "0" {
  23. t.Errorf("got x = %s, want 0", s)
  24. }
  25. z.Add(&x, &y)
  26. if s := z.RatString(); s != "0" {
  27. t.Errorf("got x+y = %s, want 0", s)
  28. }
  29. z.Sub(&x, &y)
  30. if s := z.RatString(); s != "0" {
  31. t.Errorf("got x-y = %s, want 0", s)
  32. }
  33. z.Mul(&x, &y)
  34. if s := z.RatString(); s != "0" {
  35. t.Errorf("got x*y = %s, want 0", s)
  36. }
  37. // check for division by zero
  38. defer func() {
  39. if s := recover(); s == nil || s.(string) != "division by zero" {
  40. panic(s)
  41. }
  42. }()
  43. z.Quo(&x, &y)
  44. }
  45. func TestRatSign(t *testing.T) {
  46. zero := NewRat(0, 1)
  47. for _, a := range setStringTests {
  48. x, ok := new(Rat).SetString(a.in)
  49. if !ok {
  50. continue
  51. }
  52. s := x.Sign()
  53. e := x.Cmp(zero)
  54. if s != e {
  55. t.Errorf("got %d; want %d for z = %v", s, e, &x)
  56. }
  57. }
  58. }
  59. var ratCmpTests = []struct {
  60. rat1, rat2 string
  61. out int
  62. }{
  63. {"0", "0/1", 0},
  64. {"1/1", "1", 0},
  65. {"-1", "-2/2", 0},
  66. {"1", "0", 1},
  67. {"0/1", "1/1", -1},
  68. {"-5/1434770811533343057144", "-5/1434770811533343057145", -1},
  69. {"49832350382626108453/8964749413", "49832350382626108454/8964749413", -1},
  70. {"-37414950961700930/7204075375675961", "37414950961700930/7204075375675961", -1},
  71. {"37414950961700930/7204075375675961", "74829901923401860/14408150751351922", 0},
  72. }
  73. func TestRatCmp(t *testing.T) {
  74. for i, test := range ratCmpTests {
  75. x, _ := new(Rat).SetString(test.rat1)
  76. y, _ := new(Rat).SetString(test.rat2)
  77. out := x.Cmp(y)
  78. if out != test.out {
  79. t.Errorf("#%d got out = %v; want %v", i, out, test.out)
  80. }
  81. }
  82. }
  83. func TestIsInt(t *testing.T) {
  84. one := NewInt(1)
  85. for _, a := range setStringTests {
  86. x, ok := new(Rat).SetString(a.in)
  87. if !ok {
  88. continue
  89. }
  90. i := x.IsInt()
  91. e := x.Denom().Cmp(one) == 0
  92. if i != e {
  93. t.Errorf("got IsInt(%v) == %v; want %v", x, i, e)
  94. }
  95. }
  96. }
  97. func TestRatAbs(t *testing.T) {
  98. zero := new(Rat)
  99. for _, a := range setStringTests {
  100. x, ok := new(Rat).SetString(a.in)
  101. if !ok {
  102. continue
  103. }
  104. e := new(Rat).Set(x)
  105. if e.Cmp(zero) < 0 {
  106. e.Sub(zero, e)
  107. }
  108. z := new(Rat).Abs(x)
  109. if z.Cmp(e) != 0 {
  110. t.Errorf("got Abs(%v) = %v; want %v", x, z, e)
  111. }
  112. }
  113. }
  114. func TestRatNeg(t *testing.T) {
  115. zero := new(Rat)
  116. for _, a := range setStringTests {
  117. x, ok := new(Rat).SetString(a.in)
  118. if !ok {
  119. continue
  120. }
  121. e := new(Rat).Sub(zero, x)
  122. z := new(Rat).Neg(x)
  123. if z.Cmp(e) != 0 {
  124. t.Errorf("got Neg(%v) = %v; want %v", x, z, e)
  125. }
  126. }
  127. }
  128. func TestRatInv(t *testing.T) {
  129. zero := new(Rat)
  130. for _, a := range setStringTests {
  131. x, ok := new(Rat).SetString(a.in)
  132. if !ok {
  133. continue
  134. }
  135. if x.Cmp(zero) == 0 {
  136. continue // avoid division by zero
  137. }
  138. e := new(Rat).SetFrac(x.Denom(), x.Num())
  139. z := new(Rat).Inv(x)
  140. if z.Cmp(e) != 0 {
  141. t.Errorf("got Inv(%v) = %v; want %v", x, z, e)
  142. }
  143. }
  144. }
  145. type ratBinFun func(z, x, y *Rat) *Rat
  146. type ratBinArg struct {
  147. x, y, z string
  148. }
  149. func testRatBin(t *testing.T, i int, name string, f ratBinFun, a ratBinArg) {
  150. x, _ := new(Rat).SetString(a.x)
  151. y, _ := new(Rat).SetString(a.y)
  152. z, _ := new(Rat).SetString(a.z)
  153. out := f(new(Rat), x, y)
  154. if out.Cmp(z) != 0 {
  155. t.Errorf("%s #%d got %s want %s", name, i, out, z)
  156. }
  157. }
  158. var ratBinTests = []struct {
  159. x, y string
  160. sum, prod string
  161. }{
  162. {"0", "0", "0", "0"},
  163. {"0", "1", "1", "0"},
  164. {"-1", "0", "-1", "0"},
  165. {"-1", "1", "0", "-1"},
  166. {"1", "1", "2", "1"},
  167. {"1/2", "1/2", "1", "1/4"},
  168. {"1/4", "1/3", "7/12", "1/12"},
  169. {"2/5", "-14/3", "-64/15", "-28/15"},
  170. {"4707/49292519774798173060", "-3367/70976135186689855734", "84058377121001851123459/1749296273614329067191168098769082663020", "-1760941/388732505247628681598037355282018369560"},
  171. {"-61204110018146728334/3", "-31052192278051565633/2", "-215564796870448153567/6", "950260896245257153059642991192710872711/3"},
  172. {"-854857841473707320655/4237645934602118692642972629634714039", "-18/31750379913563777419", "-27/133467566250814981", "15387441146526731771790/134546868362786310073779084329032722548987800600710485341"},
  173. {"618575745270541348005638912139/19198433543745179392300736", "-19948846211000086/637313996471", "27674141753240653/30123979153216", "-6169936206128396568797607742807090270137721977/6117715203873571641674006593837351328"},
  174. {"-3/26206484091896184128", "5/2848423294177090248", "15310893822118706237/9330894968229805033368778458685147968", "-5/24882386581946146755650075889827061248"},
  175. {"26946729/330400702820", "41563965/225583428284", "1238218672302860271/4658307703098666660055", "224002580204097/14906584649915733312176"},
  176. {"-8259900599013409474/7", "-84829337473700364773/56707961321161574960", "-468402123685491748914621885145127724451/396955729248131024720", "350340947706464153265156004876107029701/198477864624065512360"},
  177. {"575775209696864/1320203974639986246357", "29/712593081308", "410331716733912717985762465/940768218243776489278275419794956", "808/45524274987585732633"},
  178. {"1786597389946320496771/2066653520653241", "6269770/1992362624741777", "3559549865190272133656109052308126637/4117523232840525481453983149257", "8967230/3296219033"},
  179. {"-36459180403360509753/32150500941194292113930", "9381566963714/9633539", "301622077145533298008420642898530153/309723104686531919656937098270", "-3784609207827/3426986245"},
  180. }
  181. func TestRatBin(t *testing.T) {
  182. for i, test := range ratBinTests {
  183. arg := ratBinArg{test.x, test.y, test.sum}
  184. testRatBin(t, i, "Add", (*Rat).Add, arg)
  185. arg = ratBinArg{test.y, test.x, test.sum}
  186. testRatBin(t, i, "Add symmetric", (*Rat).Add, arg)
  187. arg = ratBinArg{test.sum, test.x, test.y}
  188. testRatBin(t, i, "Sub", (*Rat).Sub, arg)
  189. arg = ratBinArg{test.sum, test.y, test.x}
  190. testRatBin(t, i, "Sub symmetric", (*Rat).Sub, arg)
  191. arg = ratBinArg{test.x, test.y, test.prod}
  192. testRatBin(t, i, "Mul", (*Rat).Mul, arg)
  193. arg = ratBinArg{test.y, test.x, test.prod}
  194. testRatBin(t, i, "Mul symmetric", (*Rat).Mul, arg)
  195. if test.x != "0" {
  196. arg = ratBinArg{test.prod, test.x, test.y}
  197. testRatBin(t, i, "Quo", (*Rat).Quo, arg)
  198. }
  199. if test.y != "0" {
  200. arg = ratBinArg{test.prod, test.y, test.x}
  201. testRatBin(t, i, "Quo symmetric", (*Rat).Quo, arg)
  202. }
  203. }
  204. }
  205. func TestIssue820(t *testing.T) {
  206. x := NewRat(3, 1)
  207. y := NewRat(2, 1)
  208. z := y.Quo(x, y)
  209. q := NewRat(3, 2)
  210. if z.Cmp(q) != 0 {
  211. t.Errorf("got %s want %s", z, q)
  212. }
  213. y = NewRat(3, 1)
  214. x = NewRat(2, 1)
  215. z = y.Quo(x, y)
  216. q = NewRat(2, 3)
  217. if z.Cmp(q) != 0 {
  218. t.Errorf("got %s want %s", z, q)
  219. }
  220. x = NewRat(3, 1)
  221. z = x.Quo(x, x)
  222. q = NewRat(3, 3)
  223. if z.Cmp(q) != 0 {
  224. t.Errorf("got %s want %s", z, q)
  225. }
  226. }
  227. var setFrac64Tests = []struct {
  228. a, b int64
  229. out string
  230. }{
  231. {0, 1, "0"},
  232. {0, -1, "0"},
  233. {1, 1, "1"},
  234. {-1, 1, "-1"},
  235. {1, -1, "-1"},
  236. {-1, -1, "1"},
  237. {-9223372036854775808, -9223372036854775808, "1"},
  238. }
  239. func TestRatSetFrac64Rat(t *testing.T) {
  240. for i, test := range setFrac64Tests {
  241. x := new(Rat).SetFrac64(test.a, test.b)
  242. if x.RatString() != test.out {
  243. t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
  244. }
  245. }
  246. }
  247. func TestRatGobEncoding(t *testing.T) {
  248. var medium bytes.Buffer
  249. enc := gob.NewEncoder(&medium)
  250. dec := gob.NewDecoder(&medium)
  251. for _, test := range encodingTests {
  252. medium.Reset() // empty buffer for each test case (in case of failures)
  253. var tx Rat
  254. tx.SetString(test + ".14159265")
  255. if err := enc.Encode(&tx); err != nil {
  256. t.Errorf("encoding of %s failed: %s", &tx, err)
  257. }
  258. var rx Rat
  259. if err := dec.Decode(&rx); err != nil {
  260. t.Errorf("decoding of %s failed: %s", &tx, err)
  261. }
  262. if rx.Cmp(&tx) != 0 {
  263. t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
  264. }
  265. }
  266. }
  267. // Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero.
  268. // TODO: top-level nils.
  269. func TestGobEncodingNilRatInSlice(t *testing.T) {
  270. buf := new(bytes.Buffer)
  271. enc := gob.NewEncoder(buf)
  272. dec := gob.NewDecoder(buf)
  273. var in = make([]*Rat, 1)
  274. err := enc.Encode(&in)
  275. if err != nil {
  276. t.Errorf("gob encode failed: %q", err)
  277. }
  278. var out []*Rat
  279. err = dec.Decode(&out)
  280. if err != nil {
  281. t.Fatalf("gob decode failed: %q", err)
  282. }
  283. if len(out) != 1 {
  284. t.Fatalf("wrong len; want 1 got %d", len(out))
  285. }
  286. var zero Rat
  287. if out[0].Cmp(&zero) != 0 {
  288. t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out)
  289. }
  290. }
  291. var ratNums = []string{
  292. "-141592653589793238462643383279502884197169399375105820974944592307816406286",
  293. "-1415926535897932384626433832795028841971",
  294. "-141592653589793",
  295. "-1",
  296. "0",
  297. "1",
  298. "141592653589793",
  299. "1415926535897932384626433832795028841971",
  300. "141592653589793238462643383279502884197169399375105820974944592307816406286",
  301. }
  302. var ratDenoms = []string{
  303. "1",
  304. "718281828459045",
  305. "7182818284590452353602874713526624977572",
  306. "718281828459045235360287471352662497757247093699959574966967627724076630353",
  307. }
  308. func TestRatJSONEncoding(t *testing.T) {
  309. for _, num := range ratNums {
  310. for _, denom := range ratDenoms {
  311. var tx Rat
  312. tx.SetString(num + "/" + denom)
  313. b, err := json.Marshal(&tx)
  314. if err != nil {
  315. t.Errorf("marshaling of %s failed: %s", &tx, err)
  316. continue
  317. }
  318. var rx Rat
  319. if err := json.Unmarshal(b, &rx); err != nil {
  320. t.Errorf("unmarshaling of %s failed: %s", &tx, err)
  321. continue
  322. }
  323. if rx.Cmp(&tx) != 0 {
  324. t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
  325. }
  326. }
  327. }
  328. }
  329. func TestRatXMLEncoding(t *testing.T) {
  330. for _, num := range ratNums {
  331. for _, denom := range ratDenoms {
  332. var tx Rat
  333. tx.SetString(num + "/" + denom)
  334. b, err := xml.Marshal(&tx)
  335. if err != nil {
  336. t.Errorf("marshaling of %s failed: %s", &tx, err)
  337. continue
  338. }
  339. var rx Rat
  340. if err := xml.Unmarshal(b, &rx); err != nil {
  341. t.Errorf("unmarshaling of %s failed: %s", &tx, err)
  342. continue
  343. }
  344. if rx.Cmp(&tx) != 0 {
  345. t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
  346. }
  347. }
  348. }
  349. }
  350. func TestIssue2379(t *testing.T) {
  351. // 1) no aliasing
  352. q := NewRat(3, 2)
  353. x := new(Rat)
  354. x.SetFrac(NewInt(3), NewInt(2))
  355. if x.Cmp(q) != 0 {
  356. t.Errorf("1) got %s want %s", x, q)
  357. }
  358. // 2) aliasing of numerator
  359. x = NewRat(2, 3)
  360. x.SetFrac(NewInt(3), x.Num())
  361. if x.Cmp(q) != 0 {
  362. t.Errorf("2) got %s want %s", x, q)
  363. }
  364. // 3) aliasing of denominator
  365. x = NewRat(2, 3)
  366. x.SetFrac(x.Denom(), NewInt(2))
  367. if x.Cmp(q) != 0 {
  368. t.Errorf("3) got %s want %s", x, q)
  369. }
  370. // 4) aliasing of numerator and denominator
  371. x = NewRat(2, 3)
  372. x.SetFrac(x.Denom(), x.Num())
  373. if x.Cmp(q) != 0 {
  374. t.Errorf("4) got %s want %s", x, q)
  375. }
  376. // 5) numerator and denominator are the same
  377. q = NewRat(1, 1)
  378. x = new(Rat)
  379. n := NewInt(7)
  380. x.SetFrac(n, n)
  381. if x.Cmp(q) != 0 {
  382. t.Errorf("5) got %s want %s", x, q)
  383. }
  384. }
  385. func TestIssue3521(t *testing.T) {
  386. a := new(Int)
  387. b := new(Int)
  388. a.SetString("64375784358435883458348587", 0)
  389. b.SetString("4789759874531", 0)
  390. // 0) a raw zero value has 1 as denominator
  391. zero := new(Rat)
  392. one := NewInt(1)
  393. if zero.Denom().Cmp(one) != 0 {
  394. t.Errorf("0) got %s want %s", zero.Denom(), one)
  395. }
  396. // 1a) a zero value remains zero independent of denominator
  397. x := new(Rat)
  398. x.Denom().Set(new(Int).Neg(b))
  399. if x.Cmp(zero) != 0 {
  400. t.Errorf("1a) got %s want %s", x, zero)
  401. }
  402. // 1b) a zero value may have a denominator != 0 and != 1
  403. x.Num().Set(a)
  404. qab := new(Rat).SetFrac(a, b)
  405. if x.Cmp(qab) != 0 {
  406. t.Errorf("1b) got %s want %s", x, qab)
  407. }
  408. // 2a) an integral value becomes a fraction depending on denominator
  409. x.SetFrac64(10, 2)
  410. x.Denom().SetInt64(3)
  411. q53 := NewRat(5, 3)
  412. if x.Cmp(q53) != 0 {
  413. t.Errorf("2a) got %s want %s", x, q53)
  414. }
  415. // 2b) an integral value becomes a fraction depending on denominator
  416. x = NewRat(10, 2)
  417. x.Denom().SetInt64(3)
  418. if x.Cmp(q53) != 0 {
  419. t.Errorf("2b) got %s want %s", x, q53)
  420. }
  421. // 3) changing the numerator/denominator of a Rat changes the Rat
  422. x.SetFrac(a, b)
  423. a = x.Num()
  424. b = x.Denom()
  425. a.SetInt64(5)
  426. b.SetInt64(3)
  427. if x.Cmp(q53) != 0 {
  428. t.Errorf("3) got %s want %s", x, q53)
  429. }
  430. }
  431. func TestFloat32Distribution(t *testing.T) {
  432. // Generate a distribution of (sign, mantissa, exp) values
  433. // broader than the float32 range, and check Rat.Float32()
  434. // always picks the closest float32 approximation.
  435. var add = []int64{
  436. 0,
  437. 1,
  438. 3,
  439. 5,
  440. 7,
  441. 9,
  442. 11,
  443. }
  444. var winc, einc = uint64(1), 1 // soak test (~1.5s on x86-64)
  445. if testing.Short() {
  446. winc, einc = 5, 15 // quick test (~60ms on x86-64)
  447. }
  448. for _, sign := range "+-" {
  449. for _, a := range add {
  450. for wid := uint64(0); wid < 30; wid += winc {
  451. b := 1<<wid + a
  452. if sign == '-' {
  453. b = -b
  454. }
  455. for exp := -150; exp < 150; exp += einc {
  456. num, den := NewInt(b), NewInt(1)
  457. if exp > 0 {
  458. num.Lsh(num, uint(exp))
  459. } else {
  460. den.Lsh(den, uint(-exp))
  461. }
  462. r := new(Rat).SetFrac(num, den)
  463. f, _ := r.Float32()
  464. if !checkIsBestApprox32(t, f, r) {
  465. // Append context information.
  466. t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
  467. b, exp, f, f, math.Ldexp(float64(b), exp), r)
  468. }
  469. checkNonLossyRoundtrip32(t, f)
  470. }
  471. }
  472. }
  473. }
  474. }
  475. func TestFloat64Distribution(t *testing.T) {
  476. // Generate a distribution of (sign, mantissa, exp) values
  477. // broader than the float64 range, and check Rat.Float64()
  478. // always picks the closest float64 approximation.
  479. var add = []int64{
  480. 0,
  481. 1,
  482. 3,
  483. 5,
  484. 7,
  485. 9,
  486. 11,
  487. }
  488. var winc, einc = uint64(1), 1 // soak test (~75s on x86-64)
  489. if testing.Short() {
  490. winc, einc = 10, 500 // quick test (~12ms on x86-64)
  491. }
  492. for _, sign := range "+-" {
  493. for _, a := range add {
  494. for wid := uint64(0); wid < 60; wid += winc {
  495. b := 1<<wid + a
  496. if sign == '-' {
  497. b = -b
  498. }
  499. for exp := -1100; exp < 1100; exp += einc {
  500. num, den := NewInt(b), NewInt(1)
  501. if exp > 0 {
  502. num.Lsh(num, uint(exp))
  503. } else {
  504. den.Lsh(den, uint(-exp))
  505. }
  506. r := new(Rat).SetFrac(num, den)
  507. f, _ := r.Float64()
  508. if !checkIsBestApprox64(t, f, r) {
  509. // Append context information.
  510. t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
  511. b, exp, f, f, math.Ldexp(float64(b), exp), r)
  512. }
  513. checkNonLossyRoundtrip64(t, f)
  514. }
  515. }
  516. }
  517. }
  518. }
  519. // TestSetFloat64NonFinite checks that SetFloat64 of a non-finite value
  520. // returns nil.
  521. func TestSetFloat64NonFinite(t *testing.T) {
  522. for _, f := range []float64{math.NaN(), math.Inf(+1), math.Inf(-1)} {
  523. var r Rat
  524. if r2 := r.SetFloat64(f); r2 != nil {
  525. t.Errorf("SetFloat64(%g) was %v, want nil", f, r2)
  526. }
  527. }
  528. }
  529. // checkNonLossyRoundtrip32 checks that a float->Rat->float roundtrip is
  530. // non-lossy for finite f.
  531. func checkNonLossyRoundtrip32(t *testing.T, f float32) {
  532. if !isFinite(float64(f)) {
  533. return
  534. }
  535. r := new(Rat).SetFloat64(float64(f))
  536. if r == nil {
  537. t.Errorf("Rat.SetFloat64(float64(%g) (%b)) == nil", f, f)
  538. return
  539. }
  540. f2, exact := r.Float32()
  541. if f != f2 || !exact {
  542. t.Errorf("Rat.SetFloat64(float64(%g)).Float32() = %g (%b), %v, want %g (%b), %v; delta = %b",
  543. f, f2, f2, exact, f, f, true, f2-f)
  544. }
  545. }
  546. // checkNonLossyRoundtrip64 checks that a float->Rat->float roundtrip is
  547. // non-lossy for finite f.
  548. func checkNonLossyRoundtrip64(t *testing.T, f float64) {
  549. if !isFinite(f) {
  550. return
  551. }
  552. r := new(Rat).SetFloat64(f)
  553. if r == nil {
  554. t.Errorf("Rat.SetFloat64(%g (%b)) == nil", f, f)
  555. return
  556. }
  557. f2, exact := r.Float64()
  558. if f != f2 || !exact {
  559. t.Errorf("Rat.SetFloat64(%g).Float64() = %g (%b), %v, want %g (%b), %v; delta = %b",
  560. f, f2, f2, exact, f, f, true, f2-f)
  561. }
  562. }
  563. // delta returns the absolute difference between r and f.
  564. func delta(r *Rat, f float64) *Rat {
  565. d := new(Rat).Sub(r, new(Rat).SetFloat64(f))
  566. return d.Abs(d)
  567. }
  568. // checkIsBestApprox32 checks that f is the best possible float32
  569. // approximation of r.
  570. // Returns true on success.
  571. func checkIsBestApprox32(t *testing.T, f float32, r *Rat) bool {
  572. if math.Abs(float64(f)) >= math.MaxFloat32 {
  573. // Cannot check +Inf, -Inf, nor the float next to them (MaxFloat32).
  574. // But we have tests for these special cases.
  575. return true
  576. }
  577. // r must be strictly between f0 and f1, the floats bracketing f.
  578. f0 := math.Nextafter32(f, float32(math.Inf(-1)))
  579. f1 := math.Nextafter32(f, float32(math.Inf(+1)))
  580. // For f to be correct, r must be closer to f than to f0 or f1.
  581. df := delta(r, float64(f))
  582. df0 := delta(r, float64(f0))
  583. df1 := delta(r, float64(f1))
  584. if df.Cmp(df0) > 0 {
  585. t.Errorf("Rat(%v).Float32() = %g (%b), but previous float32 %g (%b) is closer", r, f, f, f0, f0)
  586. return false
  587. }
  588. if df.Cmp(df1) > 0 {
  589. t.Errorf("Rat(%v).Float32() = %g (%b), but next float32 %g (%b) is closer", r, f, f, f1, f1)
  590. return false
  591. }
  592. if df.Cmp(df0) == 0 && !isEven32(f) {
  593. t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
  594. return false
  595. }
  596. if df.Cmp(df1) == 0 && !isEven32(f) {
  597. t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
  598. return false
  599. }
  600. return true
  601. }
  602. // checkIsBestApprox64 checks that f is the best possible float64
  603. // approximation of r.
  604. // Returns true on success.
  605. func checkIsBestApprox64(t *testing.T, f float64, r *Rat) bool {
  606. if math.Abs(f) >= math.MaxFloat64 {
  607. // Cannot check +Inf, -Inf, nor the float next to them (MaxFloat64).
  608. // But we have tests for these special cases.
  609. return true
  610. }
  611. // r must be strictly between f0 and f1, the floats bracketing f.
  612. f0 := math.Nextafter(f, math.Inf(-1))
  613. f1 := math.Nextafter(f, math.Inf(+1))
  614. // For f to be correct, r must be closer to f than to f0 or f1.
  615. df := delta(r, f)
  616. df0 := delta(r, f0)
  617. df1 := delta(r, f1)
  618. if df.Cmp(df0) > 0 {
  619. t.Errorf("Rat(%v).Float64() = %g (%b), but previous float64 %g (%b) is closer", r, f, f, f0, f0)
  620. return false
  621. }
  622. if df.Cmp(df1) > 0 {
  623. t.Errorf("Rat(%v).Float64() = %g (%b), but next float64 %g (%b) is closer", r, f, f, f1, f1)
  624. return false
  625. }
  626. if df.Cmp(df0) == 0 && !isEven64(f) {
  627. t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
  628. return false
  629. }
  630. if df.Cmp(df1) == 0 && !isEven64(f) {
  631. t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
  632. return false
  633. }
  634. return true
  635. }
  636. func isEven32(f float32) bool { return math.Float32bits(f)&1 == 0 }
  637. func isEven64(f float64) bool { return math.Float64bits(f)&1 == 0 }
  638. func TestIsFinite(t *testing.T) {
  639. finites := []float64{
  640. 1.0 / 3,
  641. 4891559871276714924261e+222,
  642. math.MaxFloat64,
  643. math.SmallestNonzeroFloat64,
  644. -math.MaxFloat64,
  645. -math.SmallestNonzeroFloat64,
  646. }
  647. for _, f := range finites {
  648. if !isFinite(f) {
  649. t.Errorf("!IsFinite(%g (%b))", f, f)
  650. }
  651. }
  652. nonfinites := []float64{
  653. math.NaN(),
  654. math.Inf(-1),
  655. math.Inf(+1),
  656. }
  657. for _, f := range nonfinites {
  658. if isFinite(f) {
  659. t.Errorf("IsFinite(%g, (%b))", f, f)
  660. }
  661. }
  662. }