PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/axw/llgo
Go | 1694 lines | 1432 code | 146 blank | 116 comment | 324 complexity | f8885a21b779d67580b341bf5e8f256b MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2014 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. "fmt"
  7. "math"
  8. "strconv"
  9. "strings"
  10. "testing"
  11. )
  12. // Verify that ErrNaN implements the error interface.
  13. var _ error = ErrNaN{}
  14. func (x *Float) uint64() uint64 {
  15. u, acc := x.Uint64()
  16. if acc != Exact {
  17. panic(fmt.Sprintf("%s is not a uint64", x.Text('g', 10)))
  18. }
  19. return u
  20. }
  21. func (x *Float) int64() int64 {
  22. i, acc := x.Int64()
  23. if acc != Exact {
  24. panic(fmt.Sprintf("%s is not an int64", x.Text('g', 10)))
  25. }
  26. return i
  27. }
  28. func TestFloatZeroValue(t *testing.T) {
  29. // zero (uninitialized) value is a ready-to-use 0.0
  30. var x Float
  31. if s := x.Text('f', 1); s != "0.0" {
  32. t.Errorf("zero value = %s; want 0.0", s)
  33. }
  34. // zero value has precision 0
  35. if prec := x.Prec(); prec != 0 {
  36. t.Errorf("prec = %d; want 0", prec)
  37. }
  38. // zero value can be used in any and all positions of binary operations
  39. make := func(x int) *Float {
  40. var f Float
  41. if x != 0 {
  42. f.SetInt64(int64(x))
  43. }
  44. // x == 0 translates into the zero value
  45. return &f
  46. }
  47. for _, test := range []struct {
  48. z, x, y, want int
  49. opname rune
  50. op func(z, x, y *Float) *Float
  51. }{
  52. {0, 0, 0, 0, '+', (*Float).Add},
  53. {0, 1, 2, 3, '+', (*Float).Add},
  54. {1, 2, 0, 2, '+', (*Float).Add},
  55. {2, 0, 1, 1, '+', (*Float).Add},
  56. {0, 0, 0, 0, '-', (*Float).Sub},
  57. {0, 1, 2, -1, '-', (*Float).Sub},
  58. {1, 2, 0, 2, '-', (*Float).Sub},
  59. {2, 0, 1, -1, '-', (*Float).Sub},
  60. {0, 0, 0, 0, '*', (*Float).Mul},
  61. {0, 1, 2, 2, '*', (*Float).Mul},
  62. {1, 2, 0, 0, '*', (*Float).Mul},
  63. {2, 0, 1, 0, '*', (*Float).Mul},
  64. // {0, 0, 0, 0, '/', (*Float).Quo}, // panics
  65. {0, 2, 1, 2, '/', (*Float).Quo},
  66. {1, 2, 0, 0, '/', (*Float).Quo}, // = +Inf
  67. {2, 0, 1, 0, '/', (*Float).Quo},
  68. } {
  69. z := make(test.z)
  70. test.op(z, make(test.x), make(test.y))
  71. got := 0
  72. if !z.IsInf() {
  73. got = int(z.int64())
  74. }
  75. if got != test.want {
  76. t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want)
  77. }
  78. }
  79. // TODO(gri) test how precision is set for zero value results
  80. }
  81. func makeFloat(s string) *Float {
  82. x, _, err := ParseFloat(s, 0, 1000, ToNearestEven)
  83. if err != nil {
  84. panic(err)
  85. }
  86. return x
  87. }
  88. func TestFloatSetPrec(t *testing.T) {
  89. for _, test := range []struct {
  90. x string
  91. prec uint
  92. want string
  93. acc Accuracy
  94. }{
  95. // prec 0
  96. {"0", 0, "0", Exact},
  97. {"-0", 0, "-0", Exact},
  98. {"-Inf", 0, "-Inf", Exact},
  99. {"+Inf", 0, "+Inf", Exact},
  100. {"123", 0, "0", Below},
  101. {"-123", 0, "-0", Above},
  102. // prec at upper limit
  103. {"0", MaxPrec, "0", Exact},
  104. {"-0", MaxPrec, "-0", Exact},
  105. {"-Inf", MaxPrec, "-Inf", Exact},
  106. {"+Inf", MaxPrec, "+Inf", Exact},
  107. // just a few regular cases - general rounding is tested elsewhere
  108. {"1.5", 1, "2", Above},
  109. {"-1.5", 1, "-2", Below},
  110. {"123", 1e6, "123", Exact},
  111. {"-123", 1e6, "-123", Exact},
  112. } {
  113. x := makeFloat(test.x).SetPrec(test.prec)
  114. prec := test.prec
  115. if prec > MaxPrec {
  116. prec = MaxPrec
  117. }
  118. if got := x.Prec(); got != prec {
  119. t.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test.x, test.prec, got, prec)
  120. }
  121. if got, acc := x.String(), x.Acc(); got != test.want || acc != test.acc {
  122. t.Errorf("%s.SetPrec(%d) = %s (%s); want %s (%s)", test.x, test.prec, got, acc, test.want, test.acc)
  123. }
  124. }
  125. }
  126. func TestFloatMinPrec(t *testing.T) {
  127. const max = 100
  128. for _, test := range []struct {
  129. x string
  130. want uint
  131. }{
  132. {"0", 0},
  133. {"-0", 0},
  134. {"+Inf", 0},
  135. {"-Inf", 0},
  136. {"1", 1},
  137. {"2", 1},
  138. {"3", 2},
  139. {"0x8001", 16},
  140. {"0x8001p-1000", 16},
  141. {"0x8001p+1000", 16},
  142. {"0.1", max},
  143. } {
  144. x := makeFloat(test.x).SetPrec(max)
  145. if got := x.MinPrec(); got != test.want {
  146. t.Errorf("%s.MinPrec() = %d; want %d", test.x, got, test.want)
  147. }
  148. }
  149. }
  150. func TestFloatSign(t *testing.T) {
  151. for _, test := range []struct {
  152. x string
  153. s int
  154. }{
  155. {"-Inf", -1},
  156. {"-1", -1},
  157. {"-0", 0},
  158. {"+0", 0},
  159. {"+1", +1},
  160. {"+Inf", +1},
  161. } {
  162. x := makeFloat(test.x)
  163. s := x.Sign()
  164. if s != test.s {
  165. t.Errorf("%s.Sign() = %d; want %d", test.x, s, test.s)
  166. }
  167. }
  168. }
  169. // alike(x, y) is like x.Cmp(y) == 0 but also considers the sign of 0 (0 != -0).
  170. func alike(x, y *Float) bool {
  171. return x.Cmp(y) == 0 && x.Signbit() == y.Signbit()
  172. }
  173. func alike32(x, y float32) bool {
  174. // we can ignore NaNs
  175. return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y))
  176. }
  177. func alike64(x, y float64) bool {
  178. // we can ignore NaNs
  179. return x == y && math.Signbit(x) == math.Signbit(y)
  180. }
  181. func TestFloatMantExp(t *testing.T) {
  182. for _, test := range []struct {
  183. x string
  184. mant string
  185. exp int
  186. }{
  187. {"0", "0", 0},
  188. {"+0", "0", 0},
  189. {"-0", "-0", 0},
  190. {"Inf", "+Inf", 0},
  191. {"+Inf", "+Inf", 0},
  192. {"-Inf", "-Inf", 0},
  193. {"1.5", "0.75", 1},
  194. {"1.024e3", "0.5", 11},
  195. {"-0.125", "-0.5", -2},
  196. } {
  197. x := makeFloat(test.x)
  198. mant := makeFloat(test.mant)
  199. m := new(Float)
  200. e := x.MantExp(m)
  201. if !alike(m, mant) || e != test.exp {
  202. t.Errorf("%s.MantExp() = %s, %d; want %s, %d", test.x, m.Text('g', 10), e, test.mant, test.exp)
  203. }
  204. }
  205. }
  206. func TestFloatMantExpAliasing(t *testing.T) {
  207. x := makeFloat("0.5p10")
  208. if e := x.MantExp(x); e != 10 {
  209. t.Fatalf("Float.MantExp aliasing error: got %d; want 10", e)
  210. }
  211. if want := makeFloat("0.5"); !alike(x, want) {
  212. t.Fatalf("Float.MantExp aliasing error: got %s; want %s", x.Text('g', 10), want.Text('g', 10))
  213. }
  214. }
  215. func TestFloatSetMantExp(t *testing.T) {
  216. for _, test := range []struct {
  217. frac string
  218. exp int
  219. z string
  220. }{
  221. {"0", 0, "0"},
  222. {"+0", 0, "0"},
  223. {"-0", 0, "-0"},
  224. {"Inf", 1234, "+Inf"},
  225. {"+Inf", -1234, "+Inf"},
  226. {"-Inf", -1234, "-Inf"},
  227. {"0", MinExp, "0"},
  228. {"0.25", MinExp, "+0"}, // exponent underflow
  229. {"-0.25", MinExp, "-0"}, // exponent underflow
  230. {"1", MaxExp, "+Inf"}, // exponent overflow
  231. {"2", MaxExp - 1, "+Inf"}, // exponent overflow
  232. {"0.75", 1, "1.5"},
  233. {"0.5", 11, "1024"},
  234. {"-0.5", -2, "-0.125"},
  235. {"32", 5, "1024"},
  236. {"1024", -10, "1"},
  237. } {
  238. frac := makeFloat(test.frac)
  239. want := makeFloat(test.z)
  240. var z Float
  241. z.SetMantExp(frac, test.exp)
  242. if !alike(&z, want) {
  243. t.Errorf("SetMantExp(%s, %d) = %s; want %s", test.frac, test.exp, z.Text('g', 10), test.z)
  244. }
  245. // test inverse property
  246. mant := new(Float)
  247. if z.SetMantExp(mant, want.MantExp(mant)).Cmp(want) != 0 {
  248. t.Errorf("Inverse property not satisfied: got %s; want %s", z.Text('g', 10), test.z)
  249. }
  250. }
  251. }
  252. func TestFloatPredicates(t *testing.T) {
  253. for _, test := range []struct {
  254. x string
  255. sign int
  256. signbit, inf bool
  257. }{
  258. {x: "-Inf", sign: -1, signbit: true, inf: true},
  259. {x: "-1", sign: -1, signbit: true},
  260. {x: "-0", signbit: true},
  261. {x: "0"},
  262. {x: "1", sign: 1},
  263. {x: "+Inf", sign: 1, inf: true},
  264. } {
  265. x := makeFloat(test.x)
  266. if got := x.Signbit(); got != test.signbit {
  267. t.Errorf("(%s).Signbit() = %v; want %v", test.x, got, test.signbit)
  268. }
  269. if got := x.Sign(); got != test.sign {
  270. t.Errorf("(%s).Sign() = %d; want %d", test.x, got, test.sign)
  271. }
  272. if got := x.IsInf(); got != test.inf {
  273. t.Errorf("(%s).IsInf() = %v; want %v", test.x, got, test.inf)
  274. }
  275. }
  276. }
  277. func TestFloatIsInt(t *testing.T) {
  278. for _, test := range []string{
  279. "0 int",
  280. "-0 int",
  281. "1 int",
  282. "-1 int",
  283. "0.5",
  284. "1.23",
  285. "1.23e1",
  286. "1.23e2 int",
  287. "0.000000001e+8",
  288. "0.000000001e+9 int",
  289. "1.2345e200 int",
  290. "Inf",
  291. "+Inf",
  292. "-Inf",
  293. } {
  294. s := strings.TrimSuffix(test, " int")
  295. want := s != test
  296. if got := makeFloat(s).IsInt(); got != want {
  297. t.Errorf("%s.IsInt() == %t", s, got)
  298. }
  299. }
  300. }
  301. func fromBinary(s string) int64 {
  302. x, err := strconv.ParseInt(s, 2, 64)
  303. if err != nil {
  304. panic(err)
  305. }
  306. return x
  307. }
  308. func toBinary(x int64) string {
  309. return strconv.FormatInt(x, 2)
  310. }
  311. func testFloatRound(t *testing.T, x, r int64, prec uint, mode RoundingMode) {
  312. // verify test data
  313. var ok bool
  314. switch mode {
  315. case ToNearestEven, ToNearestAway:
  316. ok = true // nothing to do for now
  317. case ToZero:
  318. if x < 0 {
  319. ok = r >= x
  320. } else {
  321. ok = r <= x
  322. }
  323. case AwayFromZero:
  324. if x < 0 {
  325. ok = r <= x
  326. } else {
  327. ok = r >= x
  328. }
  329. case ToNegativeInf:
  330. ok = r <= x
  331. case ToPositiveInf:
  332. ok = r >= x
  333. default:
  334. panic("unreachable")
  335. }
  336. if !ok {
  337. t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r))
  338. }
  339. // compute expected accuracy
  340. a := Exact
  341. switch {
  342. case r < x:
  343. a = Below
  344. case r > x:
  345. a = Above
  346. }
  347. // round
  348. f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec)
  349. // check result
  350. r1 := f.int64()
  351. p1 := f.Prec()
  352. a1 := f.Acc()
  353. if r1 != r || p1 != prec || a1 != a {
  354. t.Errorf("round %s (%d bits, %s) incorrect: got %s (%d bits, %s); want %s (%d bits, %s)",
  355. toBinary(x), prec, mode,
  356. toBinary(r1), p1, a1,
  357. toBinary(r), prec, a)
  358. return
  359. }
  360. // g and f should be the same
  361. // (rounding by SetPrec after SetInt64 using default precision
  362. // should be the same as rounding by SetInt64 after setting the
  363. // precision)
  364. g := new(Float).SetMode(mode).SetPrec(prec).SetInt64(x)
  365. if !alike(g, f) {
  366. t.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s",
  367. toBinary(x), prec, mode,
  368. toBinary(g.int64()),
  369. toBinary(r1),
  370. toBinary(r),
  371. )
  372. return
  373. }
  374. // h and f should be the same
  375. // (repeated rounding should be idempotent)
  376. h := new(Float).SetMode(mode).SetPrec(prec).Set(f)
  377. if !alike(h, f) {
  378. t.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s",
  379. toBinary(x), prec, mode,
  380. toBinary(h.int64()),
  381. toBinary(r1),
  382. toBinary(r),
  383. )
  384. return
  385. }
  386. }
  387. // TestFloatRound tests basic rounding.
  388. func TestFloatRound(t *testing.T) {
  389. for _, test := range []struct {
  390. prec uint
  391. x, zero, neven, naway, away string // input, results rounded to prec bits
  392. }{
  393. {5, "1000", "1000", "1000", "1000", "1000"},
  394. {5, "1001", "1001", "1001", "1001", "1001"},
  395. {5, "1010", "1010", "1010", "1010", "1010"},
  396. {5, "1011", "1011", "1011", "1011", "1011"},
  397. {5, "1100", "1100", "1100", "1100", "1100"},
  398. {5, "1101", "1101", "1101", "1101", "1101"},
  399. {5, "1110", "1110", "1110", "1110", "1110"},
  400. {5, "1111", "1111", "1111", "1111", "1111"},
  401. {4, "1000", "1000", "1000", "1000", "1000"},
  402. {4, "1001", "1001", "1001", "1001", "1001"},
  403. {4, "1010", "1010", "1010", "1010", "1010"},
  404. {4, "1011", "1011", "1011", "1011", "1011"},
  405. {4, "1100", "1100", "1100", "1100", "1100"},
  406. {4, "1101", "1101", "1101", "1101", "1101"},
  407. {4, "1110", "1110", "1110", "1110", "1110"},
  408. {4, "1111", "1111", "1111", "1111", "1111"},
  409. {3, "1000", "1000", "1000", "1000", "1000"},
  410. {3, "1001", "1000", "1000", "1010", "1010"},
  411. {3, "1010", "1010", "1010", "1010", "1010"},
  412. {3, "1011", "1010", "1100", "1100", "1100"},
  413. {3, "1100", "1100", "1100", "1100", "1100"},
  414. {3, "1101", "1100", "1100", "1110", "1110"},
  415. {3, "1110", "1110", "1110", "1110", "1110"},
  416. {3, "1111", "1110", "10000", "10000", "10000"},
  417. {3, "1000001", "1000000", "1000000", "1000000", "1010000"},
  418. {3, "1001001", "1000000", "1010000", "1010000", "1010000"},
  419. {3, "1010001", "1010000", "1010000", "1010000", "1100000"},
  420. {3, "1011001", "1010000", "1100000", "1100000", "1100000"},
  421. {3, "1100001", "1100000", "1100000", "1100000", "1110000"},
  422. {3, "1101001", "1100000", "1110000", "1110000", "1110000"},
  423. {3, "1110001", "1110000", "1110000", "1110000", "10000000"},
  424. {3, "1111001", "1110000", "10000000", "10000000", "10000000"},
  425. {2, "1000", "1000", "1000", "1000", "1000"},
  426. {2, "1001", "1000", "1000", "1000", "1100"},
  427. {2, "1010", "1000", "1000", "1100", "1100"},
  428. {2, "1011", "1000", "1100", "1100", "1100"},
  429. {2, "1100", "1100", "1100", "1100", "1100"},
  430. {2, "1101", "1100", "1100", "1100", "10000"},
  431. {2, "1110", "1100", "10000", "10000", "10000"},
  432. {2, "1111", "1100", "10000", "10000", "10000"},
  433. {2, "1000001", "1000000", "1000000", "1000000", "1100000"},
  434. {2, "1001001", "1000000", "1000000", "1000000", "1100000"},
  435. {2, "1010001", "1000000", "1100000", "1100000", "1100000"},
  436. {2, "1011001", "1000000", "1100000", "1100000", "1100000"},
  437. {2, "1100001", "1100000", "1100000", "1100000", "10000000"},
  438. {2, "1101001", "1100000", "1100000", "1100000", "10000000"},
  439. {2, "1110001", "1100000", "10000000", "10000000", "10000000"},
  440. {2, "1111001", "1100000", "10000000", "10000000", "10000000"},
  441. {1, "1000", "1000", "1000", "1000", "1000"},
  442. {1, "1001", "1000", "1000", "1000", "10000"},
  443. {1, "1010", "1000", "1000", "1000", "10000"},
  444. {1, "1011", "1000", "1000", "1000", "10000"},
  445. {1, "1100", "1000", "10000", "10000", "10000"},
  446. {1, "1101", "1000", "10000", "10000", "10000"},
  447. {1, "1110", "1000", "10000", "10000", "10000"},
  448. {1, "1111", "1000", "10000", "10000", "10000"},
  449. {1, "1000001", "1000000", "1000000", "1000000", "10000000"},
  450. {1, "1001001", "1000000", "1000000", "1000000", "10000000"},
  451. {1, "1010001", "1000000", "1000000", "1000000", "10000000"},
  452. {1, "1011001", "1000000", "1000000", "1000000", "10000000"},
  453. {1, "1100001", "1000000", "10000000", "10000000", "10000000"},
  454. {1, "1101001", "1000000", "10000000", "10000000", "10000000"},
  455. {1, "1110001", "1000000", "10000000", "10000000", "10000000"},
  456. {1, "1111001", "1000000", "10000000", "10000000", "10000000"},
  457. } {
  458. x := fromBinary(test.x)
  459. z := fromBinary(test.zero)
  460. e := fromBinary(test.neven)
  461. n := fromBinary(test.naway)
  462. a := fromBinary(test.away)
  463. prec := test.prec
  464. testFloatRound(t, x, z, prec, ToZero)
  465. testFloatRound(t, x, e, prec, ToNearestEven)
  466. testFloatRound(t, x, n, prec, ToNearestAway)
  467. testFloatRound(t, x, a, prec, AwayFromZero)
  468. testFloatRound(t, x, z, prec, ToNegativeInf)
  469. testFloatRound(t, x, a, prec, ToPositiveInf)
  470. testFloatRound(t, -x, -a, prec, ToNegativeInf)
  471. testFloatRound(t, -x, -z, prec, ToPositiveInf)
  472. }
  473. }
  474. // TestFloatRound24 tests that rounding a float64 to 24 bits
  475. // matches IEEE-754 rounding to nearest when converting a
  476. // float64 to a float32 (excluding denormal numbers).
  477. func TestFloatRound24(t *testing.T) {
  478. const x0 = 1<<26 - 0x10 // 11...110000 (26 bits)
  479. for d := 0; d <= 0x10; d++ {
  480. x := float64(x0 + d)
  481. f := new(Float).SetPrec(24).SetFloat64(x)
  482. got, _ := f.Float32()
  483. want := float32(x)
  484. if got != want {
  485. t.Errorf("Round(%g, 24) = %g; want %g", x, got, want)
  486. }
  487. }
  488. }
  489. func TestFloatSetUint64(t *testing.T) {
  490. for _, want := range []uint64{
  491. 0,
  492. 1,
  493. 2,
  494. 10,
  495. 100,
  496. 1<<32 - 1,
  497. 1 << 32,
  498. 1<<64 - 1,
  499. } {
  500. var f Float
  501. f.SetUint64(want)
  502. if got := f.uint64(); got != want {
  503. t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
  504. }
  505. }
  506. // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
  507. const x uint64 = 0x8765432187654321 // 64 bits needed
  508. for prec := uint(1); prec <= 64; prec++ {
  509. f := new(Float).SetPrec(prec).SetMode(ToZero).SetUint64(x)
  510. got := f.uint64()
  511. want := x &^ (1<<(64-prec) - 1) // cut off (round to zero) low 64-prec bits
  512. if got != want {
  513. t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
  514. }
  515. }
  516. }
  517. func TestFloatSetInt64(t *testing.T) {
  518. for _, want := range []int64{
  519. 0,
  520. 1,
  521. 2,
  522. 10,
  523. 100,
  524. 1<<32 - 1,
  525. 1 << 32,
  526. 1<<63 - 1,
  527. } {
  528. for i := range [2]int{} {
  529. if i&1 != 0 {
  530. want = -want
  531. }
  532. var f Float
  533. f.SetInt64(want)
  534. if got := f.int64(); got != want {
  535. t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
  536. }
  537. }
  538. }
  539. // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
  540. const x int64 = 0x7654321076543210 // 63 bits needed
  541. for prec := uint(1); prec <= 63; prec++ {
  542. f := new(Float).SetPrec(prec).SetMode(ToZero).SetInt64(x)
  543. got := f.int64()
  544. want := x &^ (1<<(63-prec) - 1) // cut off (round to zero) low 63-prec bits
  545. if got != want {
  546. t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want)
  547. }
  548. }
  549. }
  550. func TestFloatSetFloat64(t *testing.T) {
  551. for _, want := range []float64{
  552. 0,
  553. 1,
  554. 2,
  555. 12345,
  556. 1e10,
  557. 1e100,
  558. 3.14159265e10,
  559. 2.718281828e-123,
  560. 1.0 / 3,
  561. math.MaxFloat32,
  562. math.MaxFloat64,
  563. math.SmallestNonzeroFloat32,
  564. math.SmallestNonzeroFloat64,
  565. math.Inf(-1),
  566. math.Inf(0),
  567. -math.Inf(1),
  568. } {
  569. for i := range [2]int{} {
  570. if i&1 != 0 {
  571. want = -want
  572. }
  573. var f Float
  574. f.SetFloat64(want)
  575. if got, acc := f.Float64(); got != want || acc != Exact {
  576. t.Errorf("got %g (%s, %s); want %g (Exact)", got, f.Text('p', 0), acc, want)
  577. }
  578. }
  579. }
  580. // test basic rounding behavior (exhaustive rounding testing is done elsewhere)
  581. const x uint64 = 0x8765432143218 // 53 bits needed
  582. for prec := uint(1); prec <= 52; prec++ {
  583. f := new(Float).SetPrec(prec).SetMode(ToZero).SetFloat64(float64(x))
  584. got, _ := f.Float64()
  585. want := float64(x &^ (1<<(52-prec) - 1)) // cut off (round to zero) low 53-prec bits
  586. if got != want {
  587. t.Errorf("got %g (%s); want %g", got, f.Text('p', 0), want)
  588. }
  589. }
  590. // test NaN
  591. defer func() {
  592. if p, ok := recover().(ErrNaN); !ok {
  593. t.Errorf("got %v; want ErrNaN panic", p)
  594. }
  595. }()
  596. var f Float
  597. f.SetFloat64(math.NaN())
  598. // should not reach here
  599. t.Errorf("got %s; want ErrNaN panic", f.Text('p', 0))
  600. }
  601. func TestFloatSetInt(t *testing.T) {
  602. for _, want := range []string{
  603. "0",
  604. "1",
  605. "-1",
  606. "1234567890",
  607. "123456789012345678901234567890",
  608. "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
  609. } {
  610. var x Int
  611. _, ok := x.SetString(want, 0)
  612. if !ok {
  613. t.Errorf("invalid integer %s", want)
  614. continue
  615. }
  616. n := x.BitLen()
  617. var f Float
  618. f.SetInt(&x)
  619. // check precision
  620. if n < 64 {
  621. n = 64
  622. }
  623. if prec := f.Prec(); prec != uint(n) {
  624. t.Errorf("got prec = %d; want %d", prec, n)
  625. }
  626. // check value
  627. got := f.Text('g', 100)
  628. if got != want {
  629. t.Errorf("got %s (%s); want %s", got, f.Text('p', 0), want)
  630. }
  631. }
  632. // TODO(gri) test basic rounding behavior
  633. }
  634. func TestFloatSetRat(t *testing.T) {
  635. for _, want := range []string{
  636. "0",
  637. "1",
  638. "-1",
  639. "1234567890",
  640. "123456789012345678901234567890",
  641. "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
  642. "1.2",
  643. "3.14159265",
  644. // TODO(gri) expand
  645. } {
  646. var x Rat
  647. _, ok := x.SetString(want)
  648. if !ok {
  649. t.Errorf("invalid fraction %s", want)
  650. continue
  651. }
  652. n := max(x.Num().BitLen(), x.Denom().BitLen())
  653. var f1, f2 Float
  654. f2.SetPrec(1000)
  655. f1.SetRat(&x)
  656. f2.SetRat(&x)
  657. // check precision when set automatically
  658. if n < 64 {
  659. n = 64
  660. }
  661. if prec := f1.Prec(); prec != uint(n) {
  662. t.Errorf("got prec = %d; want %d", prec, n)
  663. }
  664. got := f2.Text('g', 100)
  665. if got != want {
  666. t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want)
  667. }
  668. }
  669. }
  670. func TestFloatSetInf(t *testing.T) {
  671. var f Float
  672. for _, test := range []struct {
  673. signbit bool
  674. prec uint
  675. want string
  676. }{
  677. {false, 0, "+Inf"},
  678. {true, 0, "-Inf"},
  679. {false, 10, "+Inf"},
  680. {true, 30, "-Inf"},
  681. } {
  682. x := f.SetPrec(test.prec).SetInf(test.signbit)
  683. if got := x.String(); got != test.want || x.Prec() != test.prec {
  684. t.Errorf("SetInf(%v) = %s (prec = %d); want %s (prec = %d)", test.signbit, got, x.Prec(), test.want, test.prec)
  685. }
  686. }
  687. }
  688. func TestFloatUint64(t *testing.T) {
  689. for _, test := range []struct {
  690. x string
  691. out uint64
  692. acc Accuracy
  693. }{
  694. {"-Inf", 0, Above},
  695. {"-1", 0, Above},
  696. {"-1e-1000", 0, Above},
  697. {"-0", 0, Exact},
  698. {"0", 0, Exact},
  699. {"1e-1000", 0, Below},
  700. {"1", 1, Exact},
  701. {"1.000000000000000000001", 1, Below},
  702. {"12345.0", 12345, Exact},
  703. {"12345.000000000000000000001", 12345, Below},
  704. {"18446744073709551615", 18446744073709551615, Exact},
  705. {"18446744073709551615.000000000000000000001", math.MaxUint64, Below},
  706. {"18446744073709551616", math.MaxUint64, Below},
  707. {"1e10000", math.MaxUint64, Below},
  708. {"+Inf", math.MaxUint64, Below},
  709. } {
  710. x := makeFloat(test.x)
  711. out, acc := x.Uint64()
  712. if out != test.out || acc != test.acc {
  713. t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
  714. }
  715. }
  716. }
  717. func TestFloatInt64(t *testing.T) {
  718. for _, test := range []struct {
  719. x string
  720. out int64
  721. acc Accuracy
  722. }{
  723. {"-Inf", math.MinInt64, Above},
  724. {"-1e10000", math.MinInt64, Above},
  725. {"-9223372036854775809", math.MinInt64, Above},
  726. {"-9223372036854775808.000000000000000000001", math.MinInt64, Above},
  727. {"-9223372036854775808", -9223372036854775808, Exact},
  728. {"-9223372036854775807.000000000000000000001", -9223372036854775807, Above},
  729. {"-9223372036854775807", -9223372036854775807, Exact},
  730. {"-12345.000000000000000000001", -12345, Above},
  731. {"-12345.0", -12345, Exact},
  732. {"-1.000000000000000000001", -1, Above},
  733. {"-1.5", -1, Above},
  734. {"-1", -1, Exact},
  735. {"-1e-1000", 0, Above},
  736. {"0", 0, Exact},
  737. {"1e-1000", 0, Below},
  738. {"1", 1, Exact},
  739. {"1.000000000000000000001", 1, Below},
  740. {"1.5", 1, Below},
  741. {"12345.0", 12345, Exact},
  742. {"12345.000000000000000000001", 12345, Below},
  743. {"9223372036854775807", 9223372036854775807, Exact},
  744. {"9223372036854775807.000000000000000000001", math.MaxInt64, Below},
  745. {"9223372036854775808", math.MaxInt64, Below},
  746. {"1e10000", math.MaxInt64, Below},
  747. {"+Inf", math.MaxInt64, Below},
  748. } {
  749. x := makeFloat(test.x)
  750. out, acc := x.Int64()
  751. if out != test.out || acc != test.acc {
  752. t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc)
  753. }
  754. }
  755. }
  756. func TestFloatFloat32(t *testing.T) {
  757. for _, test := range []struct {
  758. x string
  759. out float32
  760. acc Accuracy
  761. }{
  762. {"0", 0, Exact},
  763. // underflow
  764. {"1e-1000", 0, Below},
  765. {"0x0.000002p-127", 0, Below},
  766. {"0x.0000010p-126", 0, Below},
  767. // denormals
  768. {"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
  769. {"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
  770. {"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
  771. {"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact},
  772. {"0x.8p-148", math.SmallestNonzeroFloat32, Exact},
  773. {"1p-149", math.SmallestNonzeroFloat32, Exact},
  774. {"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
  775. // normals
  776. {"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal
  777. {"1p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal
  778. {"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact},
  779. {"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up
  780. {"1", 1, Exact},
  781. {"1.000000000000000000001", 1, Below},
  782. {"12345.0", 12345, Exact},
  783. {"12345.000000000000000000001", 12345, Below},
  784. {"0x1.fffffe0p127", math.MaxFloat32, Exact},
  785. {"0x1.fffffe8p127", math.MaxFloat32, Below},
  786. // overflow
  787. {"0x1.ffffff0p127", float32(math.Inf(+1)), Above},
  788. {"0x1p128", float32(math.Inf(+1)), Above},
  789. {"1e10000", float32(math.Inf(+1)), Above},
  790. {"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding
  791. // inf
  792. {"Inf", float32(math.Inf(+1)), Exact},
  793. } {
  794. for i := 0; i < 2; i++ {
  795. // test both signs
  796. tx, tout, tacc := test.x, test.out, test.acc
  797. if i != 0 {
  798. tx = "-" + tx
  799. tout = -tout
  800. tacc = -tacc
  801. }
  802. // conversion should match strconv where syntax is agreeable
  803. if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) {
  804. t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
  805. }
  806. x := makeFloat(tx)
  807. out, acc := x.Float32()
  808. if !alike32(out, tout) || acc != tacc {
  809. t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
  810. }
  811. // test that x.SetFloat64(float64(f)).Float32() == f
  812. var x2 Float
  813. out2, acc2 := x2.SetFloat64(float64(out)).Float32()
  814. if !alike32(out2, out) || acc2 != Exact {
  815. t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
  816. }
  817. }
  818. }
  819. }
  820. func TestFloatFloat64(t *testing.T) {
  821. const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022
  822. for _, test := range []struct {
  823. x string
  824. out float64
  825. acc Accuracy
  826. }{
  827. {"0", 0, Exact},
  828. // underflow
  829. {"1e-1000", 0, Below},
  830. {"0x0.0000000000001p-1023", 0, Below},
  831. {"0x0.00000000000008p-1022", 0, Below},
  832. // denormals
  833. {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
  834. {"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
  835. {"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
  836. {"1p-1074", math.SmallestNonzeroFloat64, Exact},
  837. {"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
  838. // normals
  839. {"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
  840. {"1p-1022", math.Float64frombits(0x0010000000000000), Exact}, // smallest normal
  841. {"1", 1, Exact},
  842. {"1.000000000000000000001", 1, Below},
  843. {"12345.0", 12345, Exact},
  844. {"12345.000000000000000000001", 12345, Below},
  845. {"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
  846. {"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
  847. // overflow
  848. {"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
  849. {"0x1p1024", math.Inf(+1), Above},
  850. {"1e10000", math.Inf(+1), Above},
  851. {"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
  852. {"Inf", math.Inf(+1), Exact},
  853. // selected denormalized values that were handled incorrectly in the past
  854. {"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
  855. {"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
  856. // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
  857. {"2.2250738585072011e-308", 2.225073858507201e-308, Below},
  858. // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
  859. {"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
  860. } {
  861. for i := 0; i < 2; i++ {
  862. // test both signs
  863. tx, tout, tacc := test.x, test.out, test.acc
  864. if i != 0 {
  865. tx = "-" + tx
  866. tout = -tout
  867. tacc = -tacc
  868. }
  869. // conversion should match strconv where syntax is agreeable
  870. if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
  871. t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
  872. }
  873. x := makeFloat(tx)
  874. out, acc := x.Float64()
  875. if !alike64(out, tout) || acc != tacc {
  876. t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
  877. }
  878. // test that x.SetFloat64(f).Float64() == f
  879. var x2 Float
  880. out2, acc2 := x2.SetFloat64(out).Float64()
  881. if !alike64(out2, out) || acc2 != Exact {
  882. t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
  883. }
  884. }
  885. }
  886. }
  887. func TestFloatInt(t *testing.T) {
  888. for _, test := range []struct {
  889. x string
  890. want string
  891. acc Accuracy
  892. }{
  893. {"0", "0", Exact},
  894. {"+0", "0", Exact},
  895. {"-0", "0", Exact},
  896. {"Inf", "nil", Below},
  897. {"+Inf", "nil", Below},
  898. {"-Inf", "nil", Above},
  899. {"1", "1", Exact},
  900. {"-1", "-1", Exact},
  901. {"1.23", "1", Below},
  902. {"-1.23", "-1", Above},
  903. {"123e-2", "1", Below},
  904. {"123e-3", "0", Below},
  905. {"123e-4", "0", Below},
  906. {"1e-1000", "0", Below},
  907. {"-1e-1000", "0", Above},
  908. {"1e+10", "10000000000", Exact},
  909. {"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact},
  910. } {
  911. x := makeFloat(test.x)
  912. res, acc := x.Int(nil)
  913. got := "nil"
  914. if res != nil {
  915. got = res.String()
  916. }
  917. if got != test.want || acc != test.acc {
  918. t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc)
  919. }
  920. }
  921. // check that supplied *Int is used
  922. for _, f := range []string{"0", "1", "-1", "1234"} {
  923. x := makeFloat(f)
  924. i := new(Int)
  925. if res, _ := x.Int(i); res != i {
  926. t.Errorf("(%s).Int is not using supplied *Int", f)
  927. }
  928. }
  929. }
  930. func TestFloatRat(t *testing.T) {
  931. for _, test := range []struct {
  932. x, want string
  933. acc Accuracy
  934. }{
  935. {"0", "0/1", Exact},
  936. {"+0", "0/1", Exact},
  937. {"-0", "0/1", Exact},
  938. {"Inf", "nil", Below},
  939. {"+Inf", "nil", Below},
  940. {"-Inf", "nil", Above},
  941. {"1", "1/1", Exact},
  942. {"-1", "-1/1", Exact},
  943. {"1.25", "5/4", Exact},
  944. {"-1.25", "-5/4", Exact},
  945. {"1e10", "10000000000/1", Exact},
  946. {"1p10", "1024/1", Exact},
  947. {"-1p-10", "-1/1024", Exact},
  948. {"3.14159265", "7244019449799623199/2305843009213693952", Exact},
  949. } {
  950. x := makeFloat(test.x).SetPrec(64)
  951. res, acc := x.Rat(nil)
  952. got := "nil"
  953. if res != nil {
  954. got = res.String()
  955. }
  956. if got != test.want {
  957. t.Errorf("%s: got %s; want %s", test.x, got, test.want)
  958. continue
  959. }
  960. if acc != test.acc {
  961. t.Errorf("%s: got %s; want %s", test.x, acc, test.acc)
  962. continue
  963. }
  964. // inverse conversion
  965. if res != nil {
  966. got := new(Float).SetPrec(64).SetRat(res)
  967. if got.Cmp(x) != 0 {
  968. t.Errorf("%s: got %s; want %s", test.x, got, x)
  969. }
  970. }
  971. }
  972. // check that supplied *Rat is used
  973. for _, f := range []string{"0", "1", "-1", "1234"} {
  974. x := makeFloat(f)
  975. r := new(Rat)
  976. if res, _ := x.Rat(r); res != r {
  977. t.Errorf("(%s).Rat is not using supplied *Rat", f)
  978. }
  979. }
  980. }
  981. func TestFloatAbs(t *testing.T) {
  982. for _, test := range []string{
  983. "0",
  984. "1",
  985. "1234",
  986. "1.23e-2",
  987. "1e-1000",
  988. "1e1000",
  989. "Inf",
  990. } {
  991. p := makeFloat(test)
  992. a := new(Float).Abs(p)
  993. if !alike(a, p) {
  994. t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test)
  995. }
  996. n := makeFloat("-" + test)
  997. a.Abs(n)
  998. if !alike(a, p) {
  999. t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test)
  1000. }
  1001. }
  1002. }
  1003. func TestFloatNeg(t *testing.T) {
  1004. for _, test := range []string{
  1005. "0",
  1006. "1",
  1007. "1234",
  1008. "1.23e-2",
  1009. "1e-1000",
  1010. "1e1000",
  1011. "Inf",
  1012. } {
  1013. p1 := makeFloat(test)
  1014. n1 := makeFloat("-" + test)
  1015. n2 := new(Float).Neg(p1)
  1016. p2 := new(Float).Neg(n2)
  1017. if !alike(n2, n1) {
  1018. t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10))
  1019. }
  1020. if !alike(p2, p1) {
  1021. t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10))
  1022. }
  1023. }
  1024. }
  1025. func TestFloatInc(t *testing.T) {
  1026. const n = 10
  1027. for _, prec := range precList {
  1028. if 1<<prec < n {
  1029. continue // prec must be large enough to hold all numbers from 0 to n
  1030. }
  1031. var x, one Float
  1032. x.SetPrec(prec)
  1033. one.SetInt64(1)
  1034. for i := 0; i < n; i++ {
  1035. x.Add(&x, &one)
  1036. }
  1037. if x.Cmp(new(Float).SetInt64(n)) != 0 {
  1038. t.Errorf("prec = %d: got %s; want %d", prec, &x, n)
  1039. }
  1040. }
  1041. }
  1042. // Selected precisions with which to run various tests.
  1043. var precList = [...]uint{1, 2, 5, 8, 10, 16, 23, 24, 32, 50, 53, 64, 100, 128, 500, 511, 512, 513, 1000, 10000}
  1044. // Selected bits with which to run various tests.
  1045. // Each entry is a list of bits representing a floating-point number (see fromBits).
  1046. var bitsList = [...]Bits{
  1047. {}, // = 0
  1048. {0}, // = 1
  1049. {1}, // = 2
  1050. {-1}, // = 1/2
  1051. {10}, // = 2**10 == 1024
  1052. {-10}, // = 2**-10 == 1/1024
  1053. {100, 10, 1}, // = 2**100 + 2**10 + 2**1
  1054. {0, -1, -2, -10},
  1055. // TODO(gri) add more test cases
  1056. }
  1057. // TestFloatAdd tests Float.Add/Sub by comparing the result of a "manual"
  1058. // addition/subtraction of arguments represented by Bits values with the
  1059. // respective Float addition/subtraction for a variety of precisions
  1060. // and rounding modes.
  1061. func TestFloatAdd(t *testing.T) {
  1062. for _, xbits := range bitsList {
  1063. for _, ybits := range bitsList {
  1064. // exact values
  1065. x := xbits.Float()
  1066. y := ybits.Float()
  1067. zbits := xbits.add(ybits)
  1068. z := zbits.Float()
  1069. for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1070. for _, prec := range precList {
  1071. got := new(Float).SetPrec(prec).SetMode(mode)
  1072. got.Add(x, y)
  1073. want := zbits.round(prec, mode)
  1074. if got.Cmp(want) != 0 {
  1075. t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t+ %s %v\n\t= %s\n\twant %s",
  1076. i, prec, mode, x, xbits, y, ybits, got, want)
  1077. }
  1078. got.Sub(z, x)
  1079. want = ybits.round(prec, mode)
  1080. if got.Cmp(want) != 0 {
  1081. t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t- %s %v\n\t= %s\n\twant %s",
  1082. i, prec, mode, z, zbits, x, xbits, got, want)
  1083. }
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089. // TestFloatAdd32 tests that Float.Add/Sub of numbers with
  1090. // 24bit mantissa behaves like float32 addition/subtraction
  1091. // (excluding denormal numbers).
  1092. func TestFloatAdd32(t *testing.T) {
  1093. // chose base such that we cross the mantissa precision limit
  1094. const base = 1<<26 - 0x10 // 11...110000 (26 bits)
  1095. for d := 0; d <= 0x10; d++ {
  1096. for i := range [2]int{} {
  1097. x0, y0 := float64(base), float64(d)
  1098. if i&1 != 0 {
  1099. x0, y0 = y0, x0
  1100. }
  1101. x := NewFloat(x0)
  1102. y := NewFloat(y0)
  1103. z := new(Float).SetPrec(24)
  1104. z.Add(x, y)
  1105. got, acc := z.Float32()
  1106. want := float32(y0) + float32(x0)
  1107. if got != want || acc != Exact {
  1108. t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
  1109. }
  1110. z.Sub(z, y)
  1111. got, acc = z.Float32()
  1112. want = float32(want) - float32(y0)
  1113. if got != want || acc != Exact {
  1114. t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
  1115. }
  1116. }
  1117. }
  1118. }
  1119. // TestFloatAdd64 tests that Float.Add/Sub of numbers with
  1120. // 53bit mantissa behaves like float64 addition/subtraction.
  1121. func TestFloatAdd64(t *testing.T) {
  1122. // chose base such that we cross the mantissa precision limit
  1123. const base = 1<<55 - 0x10 // 11...110000 (55 bits)
  1124. for d := 0; d <= 0x10; d++ {
  1125. for i := range [2]int{} {
  1126. x0, y0 := float64(base), float64(d)
  1127. if i&1 != 0 {
  1128. x0, y0 = y0, x0
  1129. }
  1130. x := NewFloat(x0)
  1131. y := NewFloat(y0)
  1132. z := new(Float).SetPrec(53)
  1133. z.Add(x, y)
  1134. got, acc := z.Float64()
  1135. want := x0 + y0
  1136. if got != want || acc != Exact {
  1137. t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
  1138. }
  1139. z.Sub(z, y)
  1140. got, acc = z.Float64()
  1141. want -= y0
  1142. if got != want || acc != Exact {
  1143. t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
  1144. }
  1145. }
  1146. }
  1147. }
  1148. // TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
  1149. // multiplication/division of arguments represented by Bits values with the
  1150. // respective Float multiplication/division for a variety of precisions
  1151. // and rounding modes.
  1152. func TestFloatMul(t *testing.T) {
  1153. for _, xbits := range bitsList {
  1154. for _, ybits := range bitsList {
  1155. // exact values
  1156. x := xbits.Float()
  1157. y := ybits.Float()
  1158. zbits := xbits.mul(ybits)
  1159. z := zbits.Float()
  1160. for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1161. for _, prec := range precList {
  1162. got := new(Float).SetPrec(prec).SetMode(mode)
  1163. got.Mul(x, y)
  1164. want := zbits.round(prec, mode)
  1165. if got.Cmp(want) != 0 {
  1166. t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t* %s %v\n\t= %s\n\twant %s",
  1167. i, prec, mode, x, xbits, y, ybits, got, want)
  1168. }
  1169. if x.Sign() == 0 {
  1170. continue // ignore div-0 case (not invertable)
  1171. }
  1172. got.Quo(z, x)
  1173. want = ybits.round(prec, mode)
  1174. if got.Cmp(want) != 0 {
  1175. t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t/ %s %v\n\t= %s\n\twant %s",
  1176. i, prec, mode, z, zbits, x, xbits, got, want)
  1177. }
  1178. }
  1179. }
  1180. }
  1181. }
  1182. }
  1183. // TestFloatMul64 tests that Float.Mul/Quo of numbers with
  1184. // 53bit mantissa behaves like float64 multiplication/division.
  1185. func TestFloatMul64(t *testing.T) {
  1186. for _, test := range []struct {
  1187. x, y float64
  1188. }{
  1189. {0, 0},
  1190. {0, 1},
  1191. {1, 1},
  1192. {1, 1.5},
  1193. {1.234, 0.5678},
  1194. {2.718281828, 3.14159265358979},
  1195. {2.718281828e10, 3.14159265358979e-32},
  1196. {1.0 / 3, 1e200},
  1197. } {
  1198. for i := range [8]int{} {
  1199. x0, y0 := test.x, test.y
  1200. if i&1 != 0 {
  1201. x0 = -x0
  1202. }
  1203. if i&2 != 0 {
  1204. y0 = -y0
  1205. }
  1206. if i&4 != 0 {
  1207. x0, y0 = y0, x0
  1208. }
  1209. x := NewFloat(x0)
  1210. y := NewFloat(y0)
  1211. z := new(Float).SetPrec(53)
  1212. z.Mul(x, y)
  1213. got, _ := z.Float64()
  1214. want := x0 * y0
  1215. if got != want {
  1216. t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
  1217. }
  1218. if y0 == 0 {
  1219. continue // avoid division-by-zero
  1220. }
  1221. z.Quo(z, y)
  1222. got, _ = z.Float64()
  1223. want /= y0
  1224. if got != want {
  1225. t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
  1226. }
  1227. }
  1228. }
  1229. }
  1230. func TestIssue6866(t *testing.T) {
  1231. for _, prec := range precList {
  1232. two := new(Float).SetPrec(prec).SetInt64(2)
  1233. one := new(Float).SetPrec(prec).SetInt64(1)
  1234. three := new(Float).SetPrec(prec).SetInt64(3)
  1235. msix := new(Float).SetPrec(prec).SetInt64(-6)
  1236. psix := new(Float).SetPrec(prec).SetInt64(+6)
  1237. p := new(Float).SetPrec(prec)
  1238. z1 := new(Float).SetPrec(prec)
  1239. z2 := new(Float).SetPrec(prec)
  1240. // z1 = 2 + 1.0/3*-6
  1241. p.Quo(one, three)
  1242. p.Mul(p, msix)
  1243. z1.Add(two, p)
  1244. // z2 = 2 - 1.0/3*+6
  1245. p.Quo(one, three)
  1246. p.Mul(p, psix)
  1247. z2.Sub(two, p)
  1248. if z1.Cmp(z2) != 0 {
  1249. t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
  1250. }
  1251. if z1.Sign() != 0 {
  1252. t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
  1253. }
  1254. if z2.Sign() != 0 {
  1255. t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
  1256. }
  1257. }
  1258. }
  1259. func TestFloatQuo(t *testing.T) {
  1260. // TODO(gri) make the test vary these precisions
  1261. preci := 200 // precision of integer part
  1262. precf := 20 // precision of fractional part
  1263. for i := 0; i < 8; i++ {
  1264. // compute accurate (not rounded) result z
  1265. bits := Bits{preci - 1}
  1266. if i&3 != 0 {
  1267. bits = append(bits, 0)
  1268. }
  1269. if i&2 != 0 {
  1270. bits = append(bits, -1)
  1271. }
  1272. if i&1 != 0 {
  1273. bits = append(bits, -precf)
  1274. }
  1275. z := bits.Float()
  1276. // compute accurate x as z*y
  1277. y := NewFloat(3.14159265358979323e123)
  1278. x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
  1279. x.Mul(z, y)
  1280. // leave for debugging
  1281. // fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
  1282. if got := x.Acc(); got != Exact {
  1283. t.Errorf("got acc = %s; want exact", got)
  1284. }
  1285. // round accurate z for a variety of precisions and
  1286. // modes and compare against result of x / y.
  1287. for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1288. for d := -5; d < 5; d++ {
  1289. prec := uint(preci + d)
  1290. got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
  1291. want := bits.round(prec, mode)
  1292. if got.Cmp(want) != 0 {
  1293. t.Errorf("i = %d, prec = %d, %s:\n\t %s\n\t/ %s\n\t= %s\n\twant %s",
  1294. i, prec, mode, x, y, got, want)
  1295. }
  1296. }
  1297. }
  1298. }
  1299. }
  1300. // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
  1301. // it serves as a smoke test for basic correctness of division.
  1302. func TestFloatQuoSmoke(t *testing.T) {
  1303. n := 1000
  1304. if testing.Short() {
  1305. n = 10
  1306. }
  1307. const dprec = 3 // max. precision variation
  1308. const prec = 10 + dprec // enough bits to hold n precisely
  1309. for x := -n; x <= n; x++ {
  1310. for y := -n; y < n; y++ {
  1311. if y == 0 {
  1312. continue
  1313. }
  1314. a := float64(x)
  1315. b := float64(y)
  1316. c := a / b
  1317. // vary operand precision (only ok as long as a, b can be represented correctly)
  1318. for ad := -dprec; ad <= dprec; ad++ {
  1319. for bd := -dprec; bd <= dprec; bd++ {
  1320. A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
  1321. B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
  1322. C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
  1323. cc, acc := C.Float64()
  1324. if cc != c {
  1325. t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
  1326. continue
  1327. }
  1328. if acc != Exact {
  1329. t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
  1330. }
  1331. }
  1332. }
  1333. }
  1334. }
  1335. }
  1336. // TestFloatArithmeticSpecialValues tests that Float operations produce the
  1337. // correct results for combinations of zero (±0), finite (±1 and ±2.71828),
  1338. // and infinite (±Inf) operands.
  1339. func TestFloatArithmeticSpecialValues(t *testing.T) {
  1340. zero := 0.0
  1341. args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1342. xx := new(Float)
  1343. yy := new(Float)
  1344. got := new(Float)
  1345. want := new(Float)
  1346. for i := 0; i < 4; i++ {
  1347. for _, x := range args {
  1348. xx.SetFloat64(x)
  1349. // check conversion is correct
  1350. // (no need to do this for y, since we see exactly the
  1351. // same values there)
  1352. if got, acc := xx.Float64(); got != x || acc != Exact {
  1353. t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1354. }
  1355. for _, y := range args {
  1356. yy.SetFloat64(y)
  1357. var (
  1358. op string
  1359. z float64
  1360. f func(z, x, y *Float) *Float
  1361. )
  1362. switch i {
  1363. case 0:
  1364. op = "+"
  1365. z = x + y
  1366. f = (*Float).Add
  1367. case 1:
  1368. op = "-"
  1369. z = x - y
  1370. f = (*Float).Sub
  1371. case 2:
  1372. op = "*"
  1373. z = x * y
  1374. f = (*Float).Mul
  1375. case 3:
  1376. op = "/"
  1377. z = x / y
  1378. f = (*Float).Quo
  1379. default:
  1380. panic("unreachable")
  1381. }
  1382. var errnan bool // set if execution of f panicked with ErrNaN
  1383. // protect execution of f
  1384. func() {
  1385. defer func() {
  1386. if p := recover(); p != nil {
  1387. _ = p.(ErrNaN) // re-panic if not ErrNaN
  1388. errnan = true
  1389. }
  1390. }()
  1391. f(got, xx, yy)
  1392. }()
  1393. if math.IsNaN(z) {
  1394. if !errnan {
  1395. t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
  1396. }
  1397. continue
  1398. }
  1399. if errnan {
  1400. t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
  1401. continue
  1402. }
  1403. want.SetFloat64(z)
  1404. if !alike(got, want) {
  1405. t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
  1406. }
  1407. }
  1408. }
  1409. }
  1410. }
  1411. func TestFloatArithmeticOverflow(t *testing.T) {
  1412. for _, test := range []struct {
  1413. prec uint
  1414. mode RoundingMode
  1415. op byte
  1416. x, y, want string
  1417. acc Accuracy
  1418. }{
  1419. {4, ToNearestEven, '+', "0", "0", "0", Exact}, // smoke test
  1420. {4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
  1421. {4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1422. {4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
  1423. {4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in +
  1424. {4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below}, // exponent overflow in +
  1425. {4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in -
  1426. {4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
  1427. {4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
  1428. {4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
  1429. {4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below}, // exponent overflow in rounding
  1430. {4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below}, // exponent overflow in rounding
  1431. {4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
  1432. {4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
  1433. {4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
  1434. {4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1435. {4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in *
  1436. {4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
  1437. {4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1438. {4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1439. {4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
  1440. {4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
  1441. {4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
  1442. } {
  1443. x := makeFloat(test.x)
  1444. y := makeFloat(test.y)
  1445. z := new(Float).SetPrec(test.prec).SetMode(test.mode)
  1446. switch test.op {
  1447. case '+':
  1448. z.Add(x, y)
  1449. case '-':
  1450. z.Sub(x, y)
  1451. case '*':
  1452. z.Mul(x, y)
  1453. case '/':
  1454. z.Quo(x, y)
  1455. default:
  1456. panic("unreachable")
  1457. }
  1458. if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
  1459. t.Errorf(
  1460. "prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
  1461. test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
  1462. )
  1463. }
  1464. }
  1465. }
  1466. // TODO(gri) Add tests that check correctness in the presence of aliasing.
  1467. // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
  1468. // by the sign of the value to be rounded. Test that rounding happens after
  1469. // the sign of a result has been set.
  1470. // This test uses specific values that are known to fail if rounding is
  1471. // "factored" out before setting the result sign.
  1472. func TestFloatArithmeticRounding(t *testing.T) {
  1473. for _, test := range []struct {
  1474. mode RoundingMode
  1475. prec uint
  1476. x, y, want int64
  1477. op byte
  1478. }{
  1479. {ToZero, 3, -0x8, -0x1, -0x8, '+'},
  1480. {AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
  1481. {ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
  1482. {ToZero, 3, -0x8, 0x1, -0x8, '-'},
  1483. {AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
  1484. {ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
  1485. {ToZero, 3, -0x9, 0x1, -0x8, '*'},
  1486. {AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
  1487. {ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
  1488. {ToZero, 3, -0x9, 0x1, -0x8, '/'},
  1489. {AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
  1490. {ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
  1491. } {
  1492. var x, y, z Float
  1493. x.SetInt64(test.x)
  1494. y.SetInt64(test.y)
  1495. z.SetPrec(test.prec).SetMode(test.mode)
  1496. switch test.op {
  1497. case '+':
  1498. z.Add(&x, &y)
  1499. case '-':
  1500. z.Sub(&x, &y)
  1501. case '*':
  1502. z.Mul(&x, &y)
  1503. case '/':
  1504. z.Quo(&x, &y)
  1505. default:
  1506. panic("unreachable")
  1507. }
  1508. if got, acc := z.Int64(); got != test.want || acc != Exact {
  1509. t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
  1510. test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
  1511. )
  1512. }
  1513. }
  1514. }
  1515. // TestFloatCmpSpecialValues tests that Cmp produces the correct results for
  1516. // combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
  1517. // operands.
  1518. func TestFloatCmpSpecialValues(t *testing.T) {
  1519. zero := 0.0
  1520. args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1521. xx := new(Float)
  1522. yy := new(Float)
  1523. for i := 0; i < 4; i++ {
  1524. for _, x := range args {
  1525. xx.SetFloat64(x)
  1526. // check conversion is correct
  1527. // (no need to do this for y, since we see exactly the
  1528. // same values there)
  1529. if got, acc := xx.Float64(); got != x || acc != Exact {
  1530. t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1531. }
  1532. for _, y := range args {
  1533. yy.SetFloat64(y)
  1534. got := xx.Cmp(yy)
  1535. want := 0
  1536. switch {
  1537. case x < y:
  1538. want = -1
  1539. case x > y:
  1540. want = +1
  1541. }
  1542. if got != want {
  1543. t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
  1544. }
  1545. }
  1546. }
  1547. }
  1548. }