nat_test.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. // Copyright 2009 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. "io"
  7. "runtime"
  8. "strings"
  9. "testing"
  10. )
  11. var cmpTests = []struct {
  12. x, y nat
  13. r int
  14. }{
  15. {nil, nil, 0},
  16. {nil, nat(nil), 0},
  17. {nat(nil), nil, 0},
  18. {nat(nil), nat(nil), 0},
  19. {nat{0}, nat{0}, 0},
  20. {nat{0}, nat{1}, -1},
  21. {nat{1}, nat{0}, 1},
  22. {nat{1}, nat{1}, 0},
  23. {nat{0, _M}, nat{1}, 1},
  24. {nat{1}, nat{0, _M}, -1},
  25. {nat{1, _M}, nat{0, _M}, 1},
  26. {nat{0, _M}, nat{1, _M}, -1},
  27. {nat{16, 571956, 8794, 68}, nat{837, 9146, 1, 754489}, -1},
  28. {nat{34986, 41, 105, 1957}, nat{56, 7458, 104, 1957}, 1},
  29. }
  30. func TestCmp(t *testing.T) {
  31. for i, a := range cmpTests {
  32. r := a.x.cmp(a.y)
  33. if r != a.r {
  34. t.Errorf("#%d got r = %v; want %v", i, r, a.r)
  35. }
  36. }
  37. }
  38. type funNN func(z, x, y nat) nat
  39. type argNN struct {
  40. z, x, y nat
  41. }
  42. var sumNN = []argNN{
  43. {},
  44. {nat{1}, nil, nat{1}},
  45. {nat{1111111110}, nat{123456789}, nat{987654321}},
  46. {nat{0, 0, 0, 1}, nil, nat{0, 0, 0, 1}},
  47. {nat{0, 0, 0, 1111111110}, nat{0, 0, 0, 123456789}, nat{0, 0, 0, 987654321}},
  48. {nat{0, 0, 0, 1}, nat{0, 0, _M}, nat{0, 0, 1}},
  49. }
  50. var prodNN = []argNN{
  51. {},
  52. {nil, nil, nil},
  53. {nil, nat{991}, nil},
  54. {nat{991}, nat{991}, nat{1}},
  55. {nat{991 * 991}, nat{991}, nat{991}},
  56. {nat{0, 0, 991 * 991}, nat{0, 991}, nat{0, 991}},
  57. {nat{1 * 991, 2 * 991, 3 * 991, 4 * 991}, nat{1, 2, 3, 4}, nat{991}},
  58. {nat{4, 11, 20, 30, 20, 11, 4}, nat{1, 2, 3, 4}, nat{4, 3, 2, 1}},
  59. // 3^100 * 3^28 = 3^128
  60. {
  61. natFromString("11790184577738583171520872861412518665678211592275841109096961"),
  62. natFromString("515377520732011331036461129765621272702107522001"),
  63. natFromString("22876792454961"),
  64. },
  65. // z = 111....1 (70000 digits)
  66. // x = 10^(99*700) + ... + 10^1400 + 10^700 + 1
  67. // y = 111....1 (700 digits, larger than Karatsuba threshold on 32-bit and 64-bit)
  68. {
  69. natFromString(strings.Repeat("1", 70000)),
  70. natFromString("1" + strings.Repeat(strings.Repeat("0", 699)+"1", 99)),
  71. natFromString(strings.Repeat("1", 700)),
  72. },
  73. // z = 111....1 (20000 digits)
  74. // x = 10^10000 + 1
  75. // y = 111....1 (10000 digits)
  76. {
  77. natFromString(strings.Repeat("1", 20000)),
  78. natFromString("1" + strings.Repeat("0", 9999) + "1"),
  79. natFromString(strings.Repeat("1", 10000)),
  80. },
  81. }
  82. func natFromString(s string) nat {
  83. x, _, err := nat(nil).scan(strings.NewReader(s), 0)
  84. if err != nil {
  85. panic(err)
  86. }
  87. return x
  88. }
  89. func TestSet(t *testing.T) {
  90. for _, a := range sumNN {
  91. z := nat(nil).set(a.z)
  92. if z.cmp(a.z) != 0 {
  93. t.Errorf("got z = %v; want %v", z, a.z)
  94. }
  95. }
  96. }
  97. func testFunNN(t *testing.T, msg string, f funNN, a argNN) {
  98. z := f(nil, a.x, a.y)
  99. if z.cmp(a.z) != 0 {
  100. t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, z, a.z)
  101. }
  102. }
  103. func TestFunNN(t *testing.T) {
  104. for _, a := range sumNN {
  105. arg := a
  106. testFunNN(t, "add", nat.add, arg)
  107. arg = argNN{a.z, a.y, a.x}
  108. testFunNN(t, "add symmetric", nat.add, arg)
  109. arg = argNN{a.x, a.z, a.y}
  110. testFunNN(t, "sub", nat.sub, arg)
  111. arg = argNN{a.y, a.z, a.x}
  112. testFunNN(t, "sub symmetric", nat.sub, arg)
  113. }
  114. for _, a := range prodNN {
  115. arg := a
  116. testFunNN(t, "mul", nat.mul, arg)
  117. arg = argNN{a.z, a.y, a.x}
  118. testFunNN(t, "mul symmetric", nat.mul, arg)
  119. }
  120. }
  121. var mulRangesN = []struct {
  122. a, b uint64
  123. prod string
  124. }{
  125. {0, 0, "0"},
  126. {1, 1, "1"},
  127. {1, 2, "2"},
  128. {1, 3, "6"},
  129. {10, 10, "10"},
  130. {0, 100, "0"},
  131. {0, 1e9, "0"},
  132. {1, 0, "1"}, // empty range
  133. {100, 1, "1"}, // empty range
  134. {1, 10, "3628800"}, // 10!
  135. {1, 20, "2432902008176640000"}, // 20!
  136. {1, 100,
  137. "933262154439441526816992388562667004907159682643816214685929" +
  138. "638952175999932299156089414639761565182862536979208272237582" +
  139. "51185210916864000000000000000000000000", // 100!
  140. },
  141. }
  142. func TestMulRangeN(t *testing.T) {
  143. for i, r := range mulRangesN {
  144. prod := nat(nil).mulRange(r.a, r.b).decimalString()
  145. if prod != r.prod {
  146. t.Errorf("#%d: got %s; want %s", i, prod, r.prod)
  147. }
  148. }
  149. }
  150. // allocBytes returns the number of bytes allocated by invoking f.
  151. func allocBytes(f func()) uint64 {
  152. var stats runtime.MemStats
  153. runtime.ReadMemStats(&stats)
  154. t := stats.TotalAlloc
  155. f()
  156. runtime.ReadMemStats(&stats)
  157. return stats.TotalAlloc - t
  158. }
  159. // TestMulUnbalanced tests that multiplying numbers of different lengths
  160. // does not cause deep recursion and in turn allocate too much memory.
  161. // Test case for issue 3807.
  162. func TestMulUnbalanced(t *testing.T) {
  163. defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
  164. x := rndNat(50000)
  165. y := rndNat(40)
  166. allocSize := allocBytes(func() {
  167. nat(nil).mul(x, y)
  168. })
  169. inputSize := uint64(len(x)+len(y)) * _S
  170. if ratio := allocSize / uint64(inputSize); ratio > 10 {
  171. t.Errorf("multiplication uses too much memory (%d > %d times the size of inputs)", allocSize, ratio)
  172. }
  173. }
  174. func rndNat(n int) nat {
  175. return nat(rndV(n)).norm()
  176. }
  177. func BenchmarkMul(b *testing.B) {
  178. mulx := rndNat(1e4)
  179. muly := rndNat(1e4)
  180. b.ResetTimer()
  181. for i := 0; i < b.N; i++ {
  182. var z nat
  183. z.mul(mulx, muly)
  184. }
  185. }
  186. func toString(x nat, charset string) string {
  187. base := len(charset)
  188. // special cases
  189. switch {
  190. case base < 2:
  191. panic("illegal base")
  192. case len(x) == 0:
  193. return string(charset[0])
  194. }
  195. // allocate buffer for conversion
  196. i := x.bitLen()/log2(Word(base)) + 1 // +1: round up
  197. s := make([]byte, i)
  198. // don't destroy x
  199. q := nat(nil).set(x)
  200. // convert
  201. for len(q) > 0 {
  202. i--
  203. var r Word
  204. q, r = q.divW(q, Word(base))
  205. s[i] = charset[r]
  206. }
  207. return string(s[i:])
  208. }
  209. var strTests = []struct {
  210. x nat // nat value to be converted
  211. c string // conversion charset
  212. s string // expected result
  213. }{
  214. {nil, "01", "0"},
  215. {nat{1}, "01", "1"},
  216. {nat{0xc5}, "01", "11000101"},
  217. {nat{03271}, lowercaseDigits[0:8], "3271"},
  218. {nat{10}, lowercaseDigits[0:10], "10"},
  219. {nat{1234567890}, uppercaseDigits[0:10], "1234567890"},
  220. {nat{0xdeadbeef}, lowercaseDigits[0:16], "deadbeef"},
  221. {nat{0xdeadbeef}, uppercaseDigits[0:16], "DEADBEEF"},
  222. {nat{0x229be7}, lowercaseDigits[0:17], "1a2b3c"},
  223. {nat{0x309663e6}, uppercaseDigits[0:32], "O9COV6"},
  224. }
  225. func TestString(t *testing.T) {
  226. for _, a := range strTests {
  227. s := a.x.string(a.c)
  228. if s != a.s {
  229. t.Errorf("string%+v\n\tgot s = %s; want %s", a, s, a.s)
  230. }
  231. x, b, err := nat(nil).scan(strings.NewReader(a.s), len(a.c))
  232. if x.cmp(a.x) != 0 {
  233. t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
  234. }
  235. if b != len(a.c) {
  236. t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, len(a.c))
  237. }
  238. if err != nil {
  239. t.Errorf("scan%+v\n\tgot error = %s", a, err)
  240. }
  241. }
  242. }
  243. var natScanTests = []struct {
  244. s string // string to be scanned
  245. base int // input base
  246. x nat // expected nat
  247. b int // expected base
  248. ok bool // expected success
  249. next rune // next character (or 0, if at EOF)
  250. }{
  251. // error: illegal base
  252. {base: -1},
  253. {base: 1},
  254. {base: 37},
  255. // error: no mantissa
  256. {},
  257. {s: "?"},
  258. {base: 10},
  259. {base: 36},
  260. {s: "?", base: 10},
  261. {s: "0x"},
  262. {s: "345", base: 2},
  263. // no errors
  264. {"0", 0, nil, 10, true, 0},
  265. {"0", 10, nil, 10, true, 0},
  266. {"0", 36, nil, 36, true, 0},
  267. {"1", 0, nat{1}, 10, true, 0},
  268. {"1", 10, nat{1}, 10, true, 0},
  269. {"0 ", 0, nil, 10, true, ' '},
  270. {"08", 0, nil, 10, true, '8'},
  271. {"018", 0, nat{1}, 8, true, '8'},
  272. {"0b1", 0, nat{1}, 2, true, 0},
  273. {"0b11000101", 0, nat{0xc5}, 2, true, 0},
  274. {"03271", 0, nat{03271}, 8, true, 0},
  275. {"10ab", 0, nat{10}, 10, true, 'a'},
  276. {"1234567890", 0, nat{1234567890}, 10, true, 0},
  277. {"xyz", 36, nat{(33*36+34)*36 + 35}, 36, true, 0},
  278. {"xyz?", 36, nat{(33*36+34)*36 + 35}, 36, true, '?'},
  279. {"0x", 16, nil, 16, true, 'x'},
  280. {"0xdeadbeef", 0, nat{0xdeadbeef}, 16, true, 0},
  281. {"0XDEADBEEF", 0, nat{0xdeadbeef}, 16, true, 0},
  282. }
  283. func TestScanBase(t *testing.T) {
  284. for _, a := range natScanTests {
  285. r := strings.NewReader(a.s)
  286. x, b, err := nat(nil).scan(r, a.base)
  287. if err == nil && !a.ok {
  288. t.Errorf("scan%+v\n\texpected error", a)
  289. }
  290. if err != nil {
  291. if a.ok {
  292. t.Errorf("scan%+v\n\tgot error = %s", a, err)
  293. }
  294. continue
  295. }
  296. if x.cmp(a.x) != 0 {
  297. t.Errorf("scan%+v\n\tgot z = %v; want %v", a, x, a.x)
  298. }
  299. if b != a.b {
  300. t.Errorf("scan%+v\n\tgot b = %d; want %d", a, b, a.base)
  301. }
  302. next, _, err := r.ReadRune()
  303. if err == io.EOF {
  304. next = 0
  305. err = nil
  306. }
  307. if err == nil && next != a.next {
  308. t.Errorf("scan%+v\n\tgot next = %q; want %q", a, next, a.next)
  309. }
  310. }
  311. }
  312. var pi = "3" +
  313. "14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651" +
  314. "32823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461" +
  315. "28475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920" +
  316. "96282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179" +
  317. "31051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798" +
  318. "60943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901" +
  319. "22495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837" +
  320. "29780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083" +
  321. "81420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909" +
  322. "21642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151" +
  323. "55748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035" +
  324. "63707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104" +
  325. "75216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992" +
  326. "45863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818" +
  327. "34797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548" +
  328. "16136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179" +
  329. "04946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886" +
  330. "26945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645" +
  331. "99581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745" +
  332. "53050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382" +
  333. "68683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244" +
  334. "13654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767" +
  335. "88952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288" +
  336. "79710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821" +
  337. "68299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610" +
  338. "21359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435" +
  339. "06430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675" +
  340. "14269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672" +
  341. "21825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539" +
  342. "05796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007" +
  343. "23055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816" +
  344. "90915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398" +
  345. "31501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064" +
  346. "20467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325" +
  347. "97463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100" +
  348. "44929321516084244485963766983895228684783123552658213144957685726243344189303968642624341077322697802807318915" +
  349. "44110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201" +
  350. "85581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318" +
  351. "58676975145661406800700237877659134401712749470420562230538994561314071127000407854733269939081454664645880797" +
  352. "27082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923" +
  353. "09907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111" +
  354. "79042978285647503203198691514028708085990480109412147221317947647772622414254854540332157185306142288137585043" +
  355. "06332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120" +
  356. "91807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862" +
  357. "94726547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087807693259939" +
  358. "78054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229" +
  359. "24654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001" +
  360. "59377647165122893578601588161755782973523344604281512627203734314653197777416031990665541876397929334419521541" +
  361. "34189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759" +
  362. "88281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267" +
  363. "94561275318134078330336254232783944975382437205835311477119926063813346776879695970309833913077109870408591337"
  364. // Test case for BenchmarkScanPi.
  365. func TestScanPi(t *testing.T) {
  366. var x nat
  367. z, _, err := x.scan(strings.NewReader(pi), 10)
  368. if err != nil {
  369. t.Errorf("scanning pi: %s", err)
  370. }
  371. if s := z.decimalString(); s != pi {
  372. t.Errorf("scanning pi: got %s", s)
  373. }
  374. }
  375. func TestScanPiParallel(t *testing.T) {
  376. const n = 2
  377. c := make(chan int)
  378. for i := 0; i < n; i++ {
  379. go func() {
  380. TestScanPi(t)
  381. c <- 0
  382. }()
  383. }
  384. for i := 0; i < n; i++ {
  385. <-c
  386. }
  387. }
  388. func BenchmarkScanPi(b *testing.B) {
  389. for i := 0; i < b.N; i++ {
  390. var x nat
  391. x.scan(strings.NewReader(pi), 10)
  392. }
  393. }
  394. func BenchmarkStringPiParallel(b *testing.B) {
  395. var x nat
  396. x, _, _ = x.scan(strings.NewReader(pi), 0)
  397. if x.decimalString() != pi {
  398. panic("benchmark incorrect: conversion failed")
  399. }
  400. b.RunParallel(func(pb *testing.PB) {
  401. for pb.Next() {
  402. x.decimalString()
  403. }
  404. })
  405. }
  406. func BenchmarkScan10Base2(b *testing.B) { ScanHelper(b, 2, 10, 10) }
  407. func BenchmarkScan100Base2(b *testing.B) { ScanHelper(b, 2, 10, 100) }
  408. func BenchmarkScan1000Base2(b *testing.B) { ScanHelper(b, 2, 10, 1000) }
  409. func BenchmarkScan10000Base2(b *testing.B) { ScanHelper(b, 2, 10, 10000) }
  410. func BenchmarkScan100000Base2(b *testing.B) { ScanHelper(b, 2, 10, 100000) }
  411. func BenchmarkScan10Base8(b *testing.B) { ScanHelper(b, 8, 10, 10) }
  412. func BenchmarkScan100Base8(b *testing.B) { ScanHelper(b, 8, 10, 100) }
  413. func BenchmarkScan1000Base8(b *testing.B) { ScanHelper(b, 8, 10, 1000) }
  414. func BenchmarkScan10000Base8(b *testing.B) { ScanHelper(b, 8, 10, 10000) }
  415. func BenchmarkScan100000Base8(b *testing.B) { ScanHelper(b, 8, 10, 100000) }
  416. func BenchmarkScan10Base10(b *testing.B) { ScanHelper(b, 10, 10, 10) }
  417. func BenchmarkScan100Base10(b *testing.B) { ScanHelper(b, 10, 10, 100) }
  418. func BenchmarkScan1000Base10(b *testing.B) { ScanHelper(b, 10, 10, 1000) }
  419. func BenchmarkScan10000Base10(b *testing.B) { ScanHelper(b, 10, 10, 10000) }
  420. func BenchmarkScan100000Base10(b *testing.B) { ScanHelper(b, 10, 10, 100000) }
  421. func BenchmarkScan10Base16(b *testing.B) { ScanHelper(b, 16, 10, 10) }
  422. func BenchmarkScan100Base16(b *testing.B) { ScanHelper(b, 16, 10, 100) }
  423. func BenchmarkScan1000Base16(b *testing.B) { ScanHelper(b, 16, 10, 1000) }
  424. func BenchmarkScan10000Base16(b *testing.B) { ScanHelper(b, 16, 10, 10000) }
  425. func BenchmarkScan100000Base16(b *testing.B) { ScanHelper(b, 16, 10, 100000) }
  426. func ScanHelper(b *testing.B, base int, x, y Word) {
  427. b.StopTimer()
  428. var z nat
  429. z = z.expWW(x, y)
  430. var s string
  431. s = z.string(lowercaseDigits[0:base])
  432. if t := toString(z, lowercaseDigits[0:base]); t != s {
  433. b.Fatalf("scanning: got %s; want %s", s, t)
  434. }
  435. b.StartTimer()
  436. for i := 0; i < b.N; i++ {
  437. z.scan(strings.NewReader(s), base)
  438. }
  439. }
  440. func BenchmarkString10Base2(b *testing.B) { StringHelper(b, 2, 10, 10) }
  441. func BenchmarkString100Base2(b *testing.B) { StringHelper(b, 2, 10, 100) }
  442. func BenchmarkString1000Base2(b *testing.B) { StringHelper(b, 2, 10, 1000) }
  443. func BenchmarkString10000Base2(b *testing.B) { StringHelper(b, 2, 10, 10000) }
  444. func BenchmarkString100000Base2(b *testing.B) { StringHelper(b, 2, 10, 100000) }
  445. func BenchmarkString10Base8(b *testing.B) { StringHelper(b, 8, 10, 10) }
  446. func BenchmarkString100Base8(b *testing.B) { StringHelper(b, 8, 10, 100) }
  447. func BenchmarkString1000Base8(b *testing.B) { StringHelper(b, 8, 10, 1000) }
  448. func BenchmarkString10000Base8(b *testing.B) { StringHelper(b, 8, 10, 10000) }
  449. func BenchmarkString100000Base8(b *testing.B) { StringHelper(b, 8, 10, 100000) }
  450. func BenchmarkString10Base10(b *testing.B) { StringHelper(b, 10, 10, 10) }
  451. func BenchmarkString100Base10(b *testing.B) { StringHelper(b, 10, 10, 100) }
  452. func BenchmarkString1000Base10(b *testing.B) { StringHelper(b, 10, 10, 1000) }
  453. func BenchmarkString10000Base10(b *testing.B) { StringHelper(b, 10, 10, 10000) }
  454. func BenchmarkString100000Base10(b *testing.B) { StringHelper(b, 10, 10, 100000) }
  455. func BenchmarkString10Base16(b *testing.B) { StringHelper(b, 16, 10, 10) }
  456. func BenchmarkString100Base16(b *testing.B) { StringHelper(b, 16, 10, 100) }
  457. func BenchmarkString1000Base16(b *testing.B) { StringHelper(b, 16, 10, 1000) }
  458. func BenchmarkString10000Base16(b *testing.B) { StringHelper(b, 16, 10, 10000) }
  459. func BenchmarkString100000Base16(b *testing.B) { StringHelper(b, 16, 10, 100000) }
  460. func StringHelper(b *testing.B, base int, x, y Word) {
  461. b.StopTimer()
  462. var z nat
  463. z = z.expWW(x, y)
  464. z.string(lowercaseDigits[0:base]) // warm divisor cache
  465. b.StartTimer()
  466. for i := 0; i < b.N; i++ {
  467. _ = z.string(lowercaseDigits[0:base])
  468. }
  469. }
  470. func BenchmarkLeafSize0(b *testing.B) { LeafSizeHelper(b, 10, 0) } // test without splitting
  471. func BenchmarkLeafSize1(b *testing.B) { LeafSizeHelper(b, 10, 1) }
  472. func BenchmarkLeafSize2(b *testing.B) { LeafSizeHelper(b, 10, 2) }
  473. func BenchmarkLeafSize3(b *testing.B) { LeafSizeHelper(b, 10, 3) }
  474. func BenchmarkLeafSize4(b *testing.B) { LeafSizeHelper(b, 10, 4) }
  475. func BenchmarkLeafSize5(b *testing.B) { LeafSizeHelper(b, 10, 5) }
  476. func BenchmarkLeafSize6(b *testing.B) { LeafSizeHelper(b, 10, 6) }
  477. func BenchmarkLeafSize7(b *testing.B) { LeafSizeHelper(b, 10, 7) }
  478. func BenchmarkLeafSize8(b *testing.B) { LeafSizeHelper(b, 10, 8) }
  479. func BenchmarkLeafSize9(b *testing.B) { LeafSizeHelper(b, 10, 9) }
  480. func BenchmarkLeafSize10(b *testing.B) { LeafSizeHelper(b, 10, 10) }
  481. func BenchmarkLeafSize11(b *testing.B) { LeafSizeHelper(b, 10, 11) }
  482. func BenchmarkLeafSize12(b *testing.B) { LeafSizeHelper(b, 10, 12) }
  483. func BenchmarkLeafSize13(b *testing.B) { LeafSizeHelper(b, 10, 13) }
  484. func BenchmarkLeafSize14(b *testing.B) { LeafSizeHelper(b, 10, 14) }
  485. func BenchmarkLeafSize15(b *testing.B) { LeafSizeHelper(b, 10, 15) }
  486. func BenchmarkLeafSize16(b *testing.B) { LeafSizeHelper(b, 10, 16) }
  487. func BenchmarkLeafSize32(b *testing.B) { LeafSizeHelper(b, 10, 32) } // try some large lengths
  488. func BenchmarkLeafSize64(b *testing.B) { LeafSizeHelper(b, 10, 64) }
  489. func LeafSizeHelper(b *testing.B, base Word, size int) {
  490. b.StopTimer()
  491. originalLeafSize := leafSize
  492. resetTable(cacheBase10.table[:])
  493. leafSize = size
  494. b.StartTimer()
  495. for d := 1; d <= 10000; d *= 10 {
  496. b.StopTimer()
  497. var z nat
  498. z = z.expWW(base, Word(d)) // build target number
  499. _ = z.string(lowercaseDigits[0:base]) // warm divisor cache
  500. b.StartTimer()
  501. for i := 0; i < b.N; i++ {
  502. _ = z.string(lowercaseDigits[0:base])
  503. }
  504. }
  505. b.StopTimer()
  506. resetTable(cacheBase10.table[:])
  507. leafSize = originalLeafSize
  508. b.StartTimer()
  509. }
  510. func resetTable(table []divisor) {
  511. if table != nil && table[0].bbb != nil {
  512. for i := 0; i < len(table); i++ {
  513. table[i].bbb = nil
  514. table[i].nbits = 0
  515. table[i].ndigits = 0
  516. }
  517. }
  518. }
  519. func TestStringPowers(t *testing.T) {
  520. var b, p Word
  521. for b = 2; b <= 16; b++ {
  522. for p = 0; p <= 512; p++ {
  523. x := nat(nil).expWW(b, p)
  524. xs := x.string(lowercaseDigits[0:b])
  525. xs2 := toString(x, lowercaseDigits[0:b])
  526. if xs != xs2 {
  527. t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2)
  528. }
  529. }
  530. if b >= 3 && testing.Short() {
  531. break
  532. }
  533. }
  534. }
  535. func TestLeadingZeros(t *testing.T) {
  536. var x Word = _B >> 1
  537. for i := 0; i <= _W; i++ {
  538. if int(leadingZeros(x)) != i {
  539. t.Errorf("failed at %x: got %d want %d", x, leadingZeros(x), i)
  540. }
  541. x >>= 1
  542. }
  543. }
  544. type shiftTest struct {
  545. in nat
  546. shift uint
  547. out nat
  548. }
  549. var leftShiftTests = []shiftTest{
  550. {nil, 0, nil},
  551. {nil, 1, nil},
  552. {natOne, 0, natOne},
  553. {natOne, 1, natTwo},
  554. {nat{1 << (_W - 1)}, 1, nat{0}},
  555. {nat{1 << (_W - 1), 0}, 1, nat{0, 1}},
  556. }
  557. func TestShiftLeft(t *testing.T) {
  558. for i, test := range leftShiftTests {
  559. var z nat
  560. z = z.shl(test.in, test.shift)
  561. for j, d := range test.out {
  562. if j >= len(z) || z[j] != d {
  563. t.Errorf("#%d: got: %v want: %v", i, z, test.out)
  564. break
  565. }
  566. }
  567. }
  568. }
  569. var rightShiftTests = []shiftTest{
  570. {nil, 0, nil},
  571. {nil, 1, nil},
  572. {natOne, 0, natOne},
  573. {natOne, 1, nil},
  574. {natTwo, 1, natOne},
  575. {nat{0, 1}, 1, nat{1 << (_W - 1)}},
  576. {nat{2, 1, 1}, 1, nat{1<<(_W-1) + 1, 1 << (_W - 1)}},
  577. }
  578. func TestShiftRight(t *testing.T) {
  579. for i, test := range rightShiftTests {
  580. var z nat
  581. z = z.shr(test.in, test.shift)
  582. for j, d := range test.out {
  583. if j >= len(z) || z[j] != d {
  584. t.Errorf("#%d: got: %v want: %v", i, z, test.out)
  585. break
  586. }
  587. }
  588. }
  589. }
  590. type modWTest struct {
  591. in string
  592. dividend string
  593. out string
  594. }
  595. var modWTests32 = []modWTest{
  596. {"23492635982634928349238759823742", "252341", "220170"},
  597. }
  598. var modWTests64 = []modWTest{
  599. {"6527895462947293856291561095690465243862946", "524326975699234", "375066989628668"},
  600. }
  601. func runModWTests(t *testing.T, tests []modWTest) {
  602. for i, test := range tests {
  603. in, _ := new(Int).SetString(test.in, 10)
  604. d, _ := new(Int).SetString(test.dividend, 10)
  605. out, _ := new(Int).SetString(test.out, 10)
  606. r := in.abs.modW(d.abs[0])
  607. if r != out.abs[0] {
  608. t.Errorf("#%d failed: got %d want %s", i, r, out)
  609. }
  610. }
  611. }
  612. func TestModW(t *testing.T) {
  613. if _W >= 32 {
  614. runModWTests(t, modWTests32)
  615. }
  616. if _W >= 64 {
  617. runModWTests(t, modWTests64)
  618. }
  619. }
  620. func TestTrailingZeroBits(t *testing.T) {
  621. x := Word(1)
  622. for i := uint(0); i <= _W; i++ {
  623. n := trailingZeroBits(x)
  624. if n != i%_W {
  625. t.Errorf("got trailingZeroBits(%#x) = %d; want %d", x, n, i%_W)
  626. }
  627. x <<= 1
  628. }
  629. y := nat(nil).set(natOne)
  630. for i := uint(0); i <= 3*_W; i++ {
  631. n := y.trailingZeroBits()
  632. if n != i {
  633. t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.string(lowercaseDigits[0:16]), n, i)
  634. }
  635. y = y.shl(y, 1)
  636. }
  637. }
  638. var expNNTests = []struct {
  639. x, y, m string
  640. out string
  641. }{
  642. {"0", "0", "0", "1"},
  643. {"0", "0", "1", "0"},
  644. {"1", "1", "1", "0"},
  645. {"2", "1", "1", "0"},
  646. {"2", "2", "1", "0"},
  647. {"10", "100000000000", "1", "0"},
  648. {"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
  649. {"0x8000000000000000", "2", "6719", "4944"},
  650. {"0x8000000000000000", "3", "6719", "5447"},
  651. {"0x8000000000000000", "1000", "6719", "1603"},
  652. {"0x8000000000000000", "1000000", "6719", "3199"},
  653. {
  654. "2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
  655. "298472983472983471903246121093472394872319615612417471234712061",
  656. "29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
  657. "23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
  658. },
  659. }
  660. func TestExpNN(t *testing.T) {
  661. for i, test := range expNNTests {
  662. x, _, _ := nat(nil).scan(strings.NewReader(test.x), 0)
  663. y, _, _ := nat(nil).scan(strings.NewReader(test.y), 0)
  664. out, _, _ := nat(nil).scan(strings.NewReader(test.out), 0)
  665. var m nat
  666. if len(test.m) > 0 {
  667. m, _, _ = nat(nil).scan(strings.NewReader(test.m), 0)
  668. }
  669. z := nat(nil).expNN(x, y, m)
  670. if z.cmp(out) != 0 {
  671. t.Errorf("#%d got %s want %s", i, z.decimalString(), out.decimalString())
  672. }
  673. }
  674. }
  675. func ExpHelper(b *testing.B, x, y Word) {
  676. var z nat
  677. for i := 0; i < b.N; i++ {
  678. z.expWW(x, y)
  679. }
  680. }
  681. func BenchmarkExp3Power0x10(b *testing.B) { ExpHelper(b, 3, 0x10) }
  682. func BenchmarkExp3Power0x40(b *testing.B) { ExpHelper(b, 3, 0x40) }
  683. func BenchmarkExp3Power0x100(b *testing.B) { ExpHelper(b, 3, 0x100) }
  684. func BenchmarkExp3Power0x400(b *testing.B) { ExpHelper(b, 3, 0x400) }
  685. func BenchmarkExp3Power0x1000(b *testing.B) { ExpHelper(b, 3, 0x1000) }
  686. func BenchmarkExp3Power0x4000(b *testing.B) { ExpHelper(b, 3, 0x4000) }
  687. func BenchmarkExp3Power0x10000(b *testing.B) { ExpHelper(b, 3, 0x10000) }
  688. func BenchmarkExp3Power0x40000(b *testing.B) { ExpHelper(b, 3, 0x40000) }
  689. func BenchmarkExp3Power0x100000(b *testing.B) { ExpHelper(b, 3, 0x100000) }
  690. func BenchmarkExp3Power0x400000(b *testing.B) { ExpHelper(b, 3, 0x400000) }