You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

380 lines
10 KiB

  1. package inf_test
  2. import (
  3. "bytes"
  4. "encoding/gob"
  5. "fmt"
  6. "math/big"
  7. "strings"
  8. "testing"
  9. "gopkg.in/inf.v0"
  10. )
  11. type decFunZZ func(z, x, y *inf.Dec) *inf.Dec
  12. type decArgZZ struct {
  13. z, x, y *inf.Dec
  14. }
  15. var decSumZZ = []decArgZZ{
  16. {inf.NewDec(0, 0), inf.NewDec(0, 0), inf.NewDec(0, 0)},
  17. {inf.NewDec(1, 0), inf.NewDec(1, 0), inf.NewDec(0, 0)},
  18. {inf.NewDec(1111111110, 0), inf.NewDec(123456789, 0), inf.NewDec(987654321, 0)},
  19. {inf.NewDec(-1, 0), inf.NewDec(-1, 0), inf.NewDec(0, 0)},
  20. {inf.NewDec(864197532, 0), inf.NewDec(-123456789, 0), inf.NewDec(987654321, 0)},
  21. {inf.NewDec(-1111111110, 0), inf.NewDec(-123456789, 0), inf.NewDec(-987654321, 0)},
  22. {inf.NewDec(12, 2), inf.NewDec(1, 1), inf.NewDec(2, 2)},
  23. }
  24. var decProdZZ = []decArgZZ{
  25. {inf.NewDec(0, 0), inf.NewDec(0, 0), inf.NewDec(0, 0)},
  26. {inf.NewDec(0, 0), inf.NewDec(1, 0), inf.NewDec(0, 0)},
  27. {inf.NewDec(1, 0), inf.NewDec(1, 0), inf.NewDec(1, 0)},
  28. {inf.NewDec(-991*991, 0), inf.NewDec(991, 0), inf.NewDec(-991, 0)},
  29. {inf.NewDec(2, 3), inf.NewDec(1, 1), inf.NewDec(2, 2)},
  30. {inf.NewDec(2, -3), inf.NewDec(1, -1), inf.NewDec(2, -2)},
  31. {inf.NewDec(2, 3), inf.NewDec(1, 1), inf.NewDec(2, 2)},
  32. }
  33. func TestDecSignZ(t *testing.T) {
  34. var zero inf.Dec
  35. for _, a := range decSumZZ {
  36. s := a.z.Sign()
  37. e := a.z.Cmp(&zero)
  38. if s != e {
  39. t.Errorf("got %d; want %d for z = %v", s, e, a.z)
  40. }
  41. }
  42. }
  43. func TestDecAbsZ(t *testing.T) {
  44. var zero inf.Dec
  45. for _, a := range decSumZZ {
  46. var z inf.Dec
  47. z.Abs(a.z)
  48. var e inf.Dec
  49. e.Set(a.z)
  50. if e.Cmp(&zero) < 0 {
  51. e.Sub(&zero, &e)
  52. }
  53. if z.Cmp(&e) != 0 {
  54. t.Errorf("got z = %v; want %v", z, e)
  55. }
  56. }
  57. }
  58. func testDecFunZZ(t *testing.T, msg string, f decFunZZ, a decArgZZ) {
  59. var z inf.Dec
  60. f(&z, a.x, a.y)
  61. if (&z).Cmp(a.z) != 0 {
  62. t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z)
  63. }
  64. }
  65. func TestDecSumZZ(t *testing.T) {
  66. AddZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Add(x, y) }
  67. SubZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Sub(x, y) }
  68. for _, a := range decSumZZ {
  69. arg := a
  70. testDecFunZZ(t, "AddZZ", AddZZ, arg)
  71. arg = decArgZZ{a.z, a.y, a.x}
  72. testDecFunZZ(t, "AddZZ symmetric", AddZZ, arg)
  73. arg = decArgZZ{a.x, a.z, a.y}
  74. testDecFunZZ(t, "SubZZ", SubZZ, arg)
  75. arg = decArgZZ{a.y, a.z, a.x}
  76. testDecFunZZ(t, "SubZZ symmetric", SubZZ, arg)
  77. }
  78. }
  79. func TestDecProdZZ(t *testing.T) {
  80. MulZZ := func(z, x, y *inf.Dec) *inf.Dec { return z.Mul(x, y) }
  81. for _, a := range decProdZZ {
  82. arg := a
  83. testDecFunZZ(t, "MulZZ", MulZZ, arg)
  84. arg = decArgZZ{a.z, a.y, a.x}
  85. testDecFunZZ(t, "MulZZ symmetric", MulZZ, arg)
  86. }
  87. }
  88. var decUnscaledTests = []struct {
  89. d *inf.Dec
  90. u int64 // ignored when ok == false
  91. ok bool
  92. }{
  93. {new(inf.Dec), 0, true},
  94. {inf.NewDec(-1<<63, 0), -1 << 63, true},
  95. {inf.NewDec(-(-1<<63 + 1), 0), -(-1<<63 + 1), true},
  96. {new(inf.Dec).Neg(inf.NewDec(-1<<63, 0)), 0, false},
  97. {new(inf.Dec).Sub(inf.NewDec(-1<<63, 0), inf.NewDec(1, 0)), 0, false},
  98. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), 0, false},
  99. }
  100. func TestDecUnscaled(t *testing.T) {
  101. for i, tt := range decUnscaledTests {
  102. u, ok := tt.d.Unscaled()
  103. if ok != tt.ok {
  104. t.Errorf("#%d Unscaled: got %v, expected %v", i, ok, tt.ok)
  105. } else if ok && u != tt.u {
  106. t.Errorf("#%d Unscaled: got %v, expected %v", i, u, tt.u)
  107. }
  108. }
  109. }
  110. var decRoundTests = [...]struct {
  111. in *inf.Dec
  112. s inf.Scale
  113. r inf.Rounder
  114. exp *inf.Dec
  115. }{
  116. {inf.NewDec(123424999999999993, 15), 2, inf.RoundHalfUp, inf.NewDec(12342, 2)},
  117. {inf.NewDec(123425000000000001, 15), 2, inf.RoundHalfUp, inf.NewDec(12343, 2)},
  118. {inf.NewDec(123424999999999993, 15), 15, inf.RoundHalfUp, inf.NewDec(123424999999999993, 15)},
  119. {inf.NewDec(123424999999999993, 15), 16, inf.RoundHalfUp, inf.NewDec(1234249999999999930, 16)},
  120. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -1, inf.RoundHalfUp, inf.NewDec(1844674407370955162, -1)},
  121. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -2, inf.RoundHalfUp, inf.NewDec(184467440737095516, -2)},
  122. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -3, inf.RoundHalfUp, inf.NewDec(18446744073709552, -3)},
  123. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -4, inf.RoundHalfUp, inf.NewDec(1844674407370955, -4)},
  124. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -5, inf.RoundHalfUp, inf.NewDec(184467440737096, -5)},
  125. {inf.NewDecBig(new(big.Int).Lsh(big.NewInt(1), 64), 0), -6, inf.RoundHalfUp, inf.NewDec(18446744073710, -6)},
  126. }
  127. func TestDecRound(t *testing.T) {
  128. for i, tt := range decRoundTests {
  129. z := new(inf.Dec).Round(tt.in, tt.s, tt.r)
  130. if tt.exp.Cmp(z) != 0 {
  131. t.Errorf("#%d Round got %v; expected %v", i, z, tt.exp)
  132. }
  133. }
  134. }
  135. var decStringTests = []struct {
  136. in string
  137. out string
  138. val int64
  139. scale inf.Scale // skip SetString if negative
  140. ok bool
  141. scanOk bool
  142. }{
  143. {in: "", ok: false, scanOk: false},
  144. {in: "a", ok: false, scanOk: false},
  145. {in: "z", ok: false, scanOk: false},
  146. {in: "+", ok: false, scanOk: false},
  147. {in: "-", ok: false, scanOk: false},
  148. {in: "g", ok: false, scanOk: false},
  149. {in: ".", ok: false, scanOk: false},
  150. {in: ".-0", ok: false, scanOk: false},
  151. {in: ".+0", ok: false, scanOk: false},
  152. // Scannable but not SetStringable
  153. {"0b", "ignored", 0, 0, false, true},
  154. {"0x", "ignored", 0, 0, false, true},
  155. {"0xg", "ignored", 0, 0, false, true},
  156. {"0.0g", "ignored", 0, 1, false, true},
  157. // examples from godoc for Dec
  158. {"0", "0", 0, 0, true, true},
  159. {"0.00", "0.00", 0, 2, true, true},
  160. {"ignored", "0", 0, -2, true, false},
  161. {"1", "1", 1, 0, true, true},
  162. {"1.00", "1.00", 100, 2, true, true},
  163. {"10", "10", 10, 0, true, true},
  164. {"ignored", "10", 1, -1, true, false},
  165. // other tests
  166. {"+0", "0", 0, 0, true, true},
  167. {"-0", "0", 0, 0, true, true},
  168. {"0.0", "0.0", 0, 1, true, true},
  169. {"0.1", "0.1", 1, 1, true, true},
  170. {"0.", "0", 0, 0, true, true},
  171. {"-10", "-10", -1, -1, true, true},
  172. {"-1", "-1", -1, 0, true, true},
  173. {"-0.1", "-0.1", -1, 1, true, true},
  174. {"-0.01", "-0.01", -1, 2, true, true},
  175. {"+0.", "0", 0, 0, true, true},
  176. {"-0.", "0", 0, 0, true, true},
  177. {".0", "0.0", 0, 1, true, true},
  178. {"+.0", "0.0", 0, 1, true, true},
  179. {"-.0", "0.0", 0, 1, true, true},
  180. {"0.0000000000", "0.0000000000", 0, 10, true, true},
  181. {"0.0000000001", "0.0000000001", 1, 10, true, true},
  182. {"-0.0000000000", "0.0000000000", 0, 10, true, true},
  183. {"-0.0000000001", "-0.0000000001", -1, 10, true, true},
  184. {"-10", "-10", -10, 0, true, true},
  185. {"+10", "10", 10, 0, true, true},
  186. {"00", "0", 0, 0, true, true},
  187. {"023", "23", 23, 0, true, true}, // decimal, not octal
  188. {"-02.3", "-2.3", -23, 1, true, true}, // decimal, not octal
  189. }
  190. func TestDecGetString(t *testing.T) {
  191. z := new(inf.Dec)
  192. for i, test := range decStringTests {
  193. if !test.ok {
  194. continue
  195. }
  196. z.SetUnscaled(test.val)
  197. z.SetScale(test.scale)
  198. s := z.String()
  199. if s != test.out {
  200. t.Errorf("#%da got %s; want %s", i, s, test.out)
  201. }
  202. s = fmt.Sprintf("%d", z)
  203. if s != test.out {
  204. t.Errorf("#%db got %s; want %s", i, s, test.out)
  205. }
  206. }
  207. }
  208. func TestDecSetString(t *testing.T) {
  209. tmp := new(inf.Dec)
  210. for i, test := range decStringTests {
  211. if test.scale < 0 {
  212. // SetString only supports scale >= 0
  213. continue
  214. }
  215. // initialize to a non-zero value so that issues with parsing
  216. // 0 are detected
  217. tmp.Set(inf.NewDec(1234567890, 123))
  218. n1, ok1 := new(inf.Dec).SetString(test.in)
  219. n2, ok2 := tmp.SetString(test.in)
  220. expected := inf.NewDec(test.val, test.scale)
  221. if ok1 != test.ok || ok2 != test.ok {
  222. t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
  223. continue
  224. }
  225. if !ok1 {
  226. if n1 != nil {
  227. t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
  228. }
  229. continue
  230. }
  231. if !ok2 {
  232. if n2 != nil {
  233. t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
  234. }
  235. continue
  236. }
  237. if n1.Cmp(expected) != 0 {
  238. t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
  239. }
  240. if n2.Cmp(expected) != 0 {
  241. t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
  242. }
  243. }
  244. }
  245. func TestDecScan(t *testing.T) {
  246. tmp := new(inf.Dec)
  247. for i, test := range decStringTests {
  248. if test.scale < 0 {
  249. // SetString only supports scale >= 0
  250. continue
  251. }
  252. // initialize to a non-zero value so that issues with parsing
  253. // 0 are detected
  254. tmp.Set(inf.NewDec(1234567890, 123))
  255. n1, n2 := new(inf.Dec), tmp
  256. nn1, err1 := fmt.Sscan(test.in, n1)
  257. nn2, err2 := fmt.Sscan(test.in, n2)
  258. if !test.scanOk {
  259. if err1 == nil || err2 == nil {
  260. t.Errorf("#%d (input '%s') ok incorrect, should be %t", i, test.in, test.scanOk)
  261. }
  262. continue
  263. }
  264. expected := inf.NewDec(test.val, test.scale)
  265. if nn1 != 1 || err1 != nil || nn2 != 1 || err2 != nil {
  266. t.Errorf("#%d (input '%s') error %d %v, %d %v", i, test.in, nn1, err1, nn2, err2)
  267. continue
  268. }
  269. if n1.Cmp(expected) != 0 {
  270. t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
  271. }
  272. if n2.Cmp(expected) != 0 {
  273. t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
  274. }
  275. }
  276. }
  277. var decScanNextTests = []struct {
  278. in string
  279. ok bool
  280. next rune
  281. }{
  282. {"", false, 0},
  283. {"a", false, 'a'},
  284. {"z", false, 'z'},
  285. {"+", false, 0},
  286. {"-", false, 0},
  287. {"g", false, 'g'},
  288. {".", false, 0},
  289. {".-0", false, '-'},
  290. {".+0", false, '+'},
  291. {"0b", true, 'b'},
  292. {"0x", true, 'x'},
  293. {"0xg", true, 'x'},
  294. {"0.0g", true, 'g'},
  295. }
  296. func TestDecScanNext(t *testing.T) {
  297. for i, test := range decScanNextTests {
  298. rdr := strings.NewReader(test.in)
  299. n1 := new(inf.Dec)
  300. nn1, _ := fmt.Fscan(rdr, n1)
  301. if (test.ok && nn1 == 0) || (!test.ok && nn1 > 0) {
  302. t.Errorf("#%d (input '%s') ok incorrect should be %t", i, test.in, test.ok)
  303. continue
  304. }
  305. r := rune(0)
  306. nn2, err := fmt.Fscanf(rdr, "%c", &r)
  307. if test.next != r {
  308. t.Errorf("#%d (input '%s') next incorrect, got %c should be %c, %d, %v", i, test.in, r, test.next, nn2, err)
  309. }
  310. }
  311. }
  312. var decGobEncodingTests = []string{
  313. "0",
  314. "1",
  315. "2",
  316. "10",
  317. "42",
  318. "1234567890",
  319. "298472983472983471903246121093472394872319615612417471234712061",
  320. }
  321. func TestDecGobEncoding(t *testing.T) {
  322. var medium bytes.Buffer
  323. enc := gob.NewEncoder(&medium)
  324. dec := gob.NewDecoder(&medium)
  325. for i, test := range decGobEncodingTests {
  326. for j := 0; j < 2; j++ {
  327. for k := inf.Scale(-5); k <= 5; k++ {
  328. medium.Reset() // empty buffer for each test case (in case of failures)
  329. stest := test
  330. if j != 0 {
  331. // negative numbers
  332. stest = "-" + test
  333. }
  334. var tx inf.Dec
  335. tx.SetString(stest)
  336. tx.SetScale(k) // test with positive, negative, and zero scale
  337. if err := enc.Encode(&tx); err != nil {
  338. t.Errorf("#%d%c: encoding failed: %s", i, 'a'+j, err)
  339. }
  340. var rx inf.Dec
  341. if err := dec.Decode(&rx); err != nil {
  342. t.Errorf("#%d%c: decoding failed: %s", i, 'a'+j, err)
  343. }
  344. if rx.Cmp(&tx) != 0 {
  345. t.Errorf("#%d%c: transmission failed: got %s want %s", i, 'a'+j, &rx, &tx)
  346. }
  347. }
  348. }
  349. }
  350. }