mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
533 lines
26 KiB
V
533 lines
26 KiB
V
import math.big
|
|
|
|
fn test_integer_from_int() {
|
|
assert big.integer_from_int(0).hex() == '0'
|
|
assert big.integer_from_int(1).hex() == '1'
|
|
assert big.integer_from_int(255).hex() == 'ff'
|
|
assert big.integer_from_int(127).hex() == '7f'
|
|
assert big.integer_from_int(1024).hex() == '400'
|
|
assert big.integer_from_int(2147483647).hex() == '7fffffff'
|
|
}
|
|
|
|
fn test_integer_from_u64() {
|
|
assert big.integer_from_u64(0).hex() == '0'
|
|
assert big.integer_from_u64(1).hex() == '1'
|
|
assert big.integer_from_u64(255).hex() == 'ff'
|
|
assert big.integer_from_u64(127).hex() == '7f'
|
|
assert big.integer_from_u64(1024).hex() == '400'
|
|
assert big.integer_from_u64(4294967295).hex() == 'ffffffff'
|
|
assert big.integer_from_u64(4398046511104).hex() == '40000000000'
|
|
max_value := big.integer_from_u64(u64(-1))
|
|
|
|
assert max_value.hex() == 'ffffffffffffffff'
|
|
}
|
|
|
|
fn test_integer_from_bytes() {
|
|
assert big.integer_from_bytes([]).hex() == '0'
|
|
assert big.integer_from_bytes([u8(0)]).hex() == '0'
|
|
assert big.integer_from_bytes([u8(0x13), 0x37]).hex() == '1337'
|
|
assert big.integer_from_bytes([u8(0x13), 0x37, 0xca]).hex() == '1337ca'
|
|
assert big.integer_from_bytes([u8(0x13), 0x37, 0xca, 0xfe]).hex() == '1337cafe'
|
|
assert big.integer_from_bytes([u8(0x13), 0x37, 0xca, 0xfe, 0xba]).hex() == '1337cafeba'
|
|
assert big.integer_from_bytes([u8(0x13), 0x37, 0xca, 0xfe, 0xba, 0xbe]).hex() == '1337cafebabe'
|
|
|
|
mut bytes := []u8{cap: 1024}
|
|
mut expected := ''
|
|
for i := 0; i < bytes.cap; i++ {
|
|
bytes << u8(i)
|
|
expected = expected + u8(i).hex()
|
|
}
|
|
assert big.integer_from_bytes(bytes).hex() == expected.trim_left('0')
|
|
}
|
|
|
|
fn test_bytes() {
|
|
result1, sign1 := big.integer_from_u64(0x1337cafebabe).bytes()
|
|
assert result1 == [u8(0x13), 0x37, 0xca, 0xfe, 0xba, 0xbe]
|
|
assert sign1 == 1
|
|
|
|
mut bytes := []u8{cap: 1024}
|
|
mut expected := ''
|
|
for i := 0; i < bytes.cap; i++ {
|
|
bytes << u8(i | 1)
|
|
expected = expected + u8(i).hex()
|
|
}
|
|
result2, sign2 := big.integer_from_bytes(bytes).bytes()
|
|
assert result2 == bytes
|
|
assert sign2 == 1
|
|
}
|
|
|
|
fn test_addition() {
|
|
a := big.integer_from_int(2)
|
|
b := big.integer_from_int(3)
|
|
c := a + b
|
|
assert c.hex() == '5'
|
|
|
|
assert (big.integer_from_int(1024) + big.integer_from_int(1024)).hex() == '800'
|
|
|
|
fib1 := big.integer_from_string('84885164052257330097714121751630835360966663883732297726369399') or {
|
|
panic('Cannot read decimal')
|
|
}
|
|
fib2 := big.integer_from_string('137347080577163115432025771710279131845700275212767467264610201') or {
|
|
panic('Cannot read decimal')
|
|
}
|
|
assert (fib1 + fib2).str() == '222232244629420445529739893461909967206666939096499764990979600'
|
|
}
|
|
|
|
fn test_subtraction() {
|
|
a := big.integer_from_int(2)
|
|
b := big.integer_from_int(3)
|
|
assert (a - b).hex() == '-1'
|
|
assert (b - a).hex() == '1'
|
|
|
|
c := big.integer_from_int(1024)
|
|
assert (c - c) == big.zero_int
|
|
|
|
assert big.integer_from_int(-37) - big.integer_from_int(-54) == big.integer_from_int(17)
|
|
}
|
|
|
|
fn test_multiplication() {
|
|
a := big.integer_from_int(2)
|
|
b := big.integer_from_int(3)
|
|
c := big.integer_from_int(6)
|
|
assert a * b == c
|
|
assert big.integer_from_int(-869) * big.integer_from_int(789) == big.integer_from_int(-685641)
|
|
e := big.integer_from_u32(1024)
|
|
e2 := e * e
|
|
e4 := e2 * e2
|
|
e8 := e2 * e2 * e2 * e2
|
|
e9 := e8 + big.one_int
|
|
d := ((e9 * e9) + b) * c
|
|
assert e4.hex() == '10000000000'
|
|
assert e8.hex() == '100000000000000000000'
|
|
assert e9.hex() == '100000000000000000001'
|
|
assert d.hex() == '60000000000000000000c00000000000000000018'
|
|
}
|
|
|
|
fn test_division() {
|
|
a := big.integer_from_u64(2)
|
|
b := big.integer_from_u64(3)
|
|
c := b / a
|
|
assert c.hex() == '1'
|
|
assert (b % a).hex() == '1'
|
|
e := big.integer_from_u64(1024) // dec(1024) == hex(0x400)
|
|
ee := e / e
|
|
assert ee.hex() == '1'
|
|
assert (e / a).hex() == '200'
|
|
assert (e / (a * a)).hex() == '100'
|
|
|
|
assert (b / a).hex() == '1'
|
|
}
|
|
|
|
fn test_mod() {
|
|
assert (big.integer_from_u64(13) % big.integer_from_u64(10)).int() == 3
|
|
assert (big.integer_from_u64(13) % big.integer_from_u64(9)).int() == 4
|
|
assert (big.integer_from_u64(7) % big.integer_from_u64(5)).int() == 2
|
|
}
|
|
|
|
struct DivisionTest {
|
|
dividend string
|
|
divisor string
|
|
quotient string
|
|
remainder string
|
|
}
|
|
|
|
const divmod_test_data = [
|
|
DivisionTest{'13', '10', '1', '3'},
|
|
DivisionTest{'13', '9', '1', '4'},
|
|
DivisionTest{'7', '5', '1', '2'},
|
|
DivisionTest{'2103180314840157', '1631403814113', '1289', '300798448500'},
|
|
DivisionTest{'21408410031413414147401', '3130541314113413', '6838564', '2900204736088469'}
|
|
// vfmt off
|
|
DivisionTest{
|
|
'13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096',
|
|
'13407807926845237209807376456131917626043958556151178674833163543294276330515137663421134775482798690129946803802212663956180562088664022929883876655300863',
|
|
'1',
|
|
'3097359889766648542073928501435407264441214702890397900427487699558409313380739522684104737560085054384273386897573320723282547016549772350783233',
|
|
},
|
|
DivisionTest{
|
|
'24388660549343689307666288436614463270948472382596516055139370678271628439810393042585576900667596857198513726355043536294702186342478937800831',
|
|
'38733748171303628844838787580045178098452927239062690602450784467058896912531690007767956310348951731921168881868406259712',
|
|
'629648864382619361826',
|
|
'2724578611525334851445652767465274410979805962941953382558409365935061481311529445551691298696266856092833571769883246719',
|
|
},
|
|
// vfmt on
|
|
]
|
|
|
|
fn test_divmod() {
|
|
for t in divmod_test_data {
|
|
a := big.integer_from_string(t.dividend) or { panic('Cannot read decimal') }
|
|
b := big.integer_from_string(t.divisor) or { panic('Cannot read decimal') }
|
|
eq := big.integer_from_string(t.quotient) or { panic('Cannot read decimal') }
|
|
er := big.integer_from_string(t.remainder) or { panic('Cannot read decimal') }
|
|
|
|
q, r := a.div_mod(b)
|
|
assert q == eq
|
|
assert r == er
|
|
}
|
|
}
|
|
|
|
fn test_comparison() {
|
|
values := [-3, 13, 52, 6, 41]
|
|
for value in values {
|
|
x := big.integer_from_int(value)
|
|
assert x == x
|
|
assert x <= x
|
|
assert x >= x
|
|
}
|
|
|
|
a := big.integer_from_int(-45)
|
|
b := big.integer_from_int(35)
|
|
|
|
assert a < b
|
|
assert a <= b
|
|
assert b > a
|
|
assert b >= a
|
|
}
|
|
|
|
fn test_conversion() {
|
|
ten := big.integer_from_int(10)
|
|
|
|
mut n := big.integer_from_u64(u64(-1))
|
|
|
|
mut digits := []rune{}
|
|
for n.signum != 0 {
|
|
quot, rem := n.div_mod(ten)
|
|
digits << rune(rem.int()) + `0`
|
|
n = quot
|
|
}
|
|
|
|
assert digits.reverse().string() == '18446744073709551615'
|
|
}
|
|
|
|
fn test_integer_from_string() {
|
|
a := big.integer_from_string('00000000') or { panic('Zero int test fails') }
|
|
assert a == big.zero_int
|
|
b := big.integer_from_radix('00', 4) or { panic('Zero int test fails') }
|
|
assert b == big.zero_int
|
|
assert a == b
|
|
|
|
string_values := ['0', '1', '0012', '1349173614', '+24', '-325']
|
|
int_values := [0, 1, 12, 1349173614, 24, -325]
|
|
for index in 0 .. string_values.len {
|
|
x := big.integer_from_string(string_values[index]) or {
|
|
panic('Could not convert decimal string')
|
|
}
|
|
y := big.integer_from_int(int_values[index])
|
|
assert x == y
|
|
}
|
|
|
|
imin := big.integer_from_string('-2147483648') or {
|
|
panic('Minimum signed 32-bit int test fails.')
|
|
}
|
|
assert imin.int() == -2147483648
|
|
|
|
imax := big.integer_from_string('2147483647') or {
|
|
panic('Maximum signed 32-bit int test fails.')
|
|
}
|
|
assert imax.int() == 2147483647
|
|
}
|
|
|
|
fn test_integer_from_powers_of_2() {
|
|
assert (big.integer_from_radix('101010', 2) or { panic('Cannot read binary') }).int() == 42
|
|
assert (big.integer_from_radix('1010', 2) or { panic('Cannot read binary') }).int() == 10
|
|
assert (big.integer_from_radix('-0000101', 2) or { panic('Cannot read binary') }).int() == -5
|
|
|
|
assert (big.integer_from_radix('CAFE', 16) or { panic('Cannot read hexadecimal') }).int() == 0xCAFE
|
|
assert (big.integer_from_radix('DED', 16) or { panic('Cannot read hexadecimal') }).int() == 0xDED
|
|
assert (big.integer_from_radix('-abcd', 16) or { panic('Cannot read hexadecimal') }).int() == -0xabcd
|
|
}
|
|
|
|
fn test_from_and_to_hex() {
|
|
assert (big.integer_from_radix('123', 16) or { panic('Cannot read hexadecimal') }).hex() == '123'
|
|
for i in 1 .. 33 {
|
|
input := 'e'.repeat(i)
|
|
output := (big.integer_from_radix(input, 16) or { panic('Cannot read hexadecimal') }).hex()
|
|
assert input == output
|
|
}
|
|
assert (big.integer_from_string('0') or { panic('Cannot read decimal') }).str() == '0'
|
|
}
|
|
|
|
fn test_str() {
|
|
assert big.integer_from_u64(255).str() == '255'
|
|
assert big.integer_from_u64(127).str() == '127'
|
|
assert big.integer_from_u64(1024).str() == '1024'
|
|
assert big.integer_from_u64(4294967295).str() == '4294967295'
|
|
assert big.integer_from_u64(4398046511104).str() == '4398046511104'
|
|
assert big.integer_from_u64(u64(-1)).str() == '18446744073709551615'
|
|
assert (big.integer_from_radix('e'.repeat(80), 16) or { panic('Cannot read hexadecimal') }).str() == '1993587900192849410235353592424915306962524220866209251950572167300738410728597846688097947807470'
|
|
}
|
|
|
|
fn test_exponentiation() {
|
|
a := big.integer_from_int(2)
|
|
assert a.pow(0).int() == 1
|
|
assert a.pow(1).int() == 2
|
|
assert a.pow(5).int() == 32
|
|
assert a.pow(10).int() == 1024
|
|
assert a.pow(30).int() == 1073741824
|
|
|
|
exp_array := [u32(5), 7, 234, 524, 291, 13051]
|
|
for exp in exp_array {
|
|
expected := '1' + '0'.repeat(int(exp))
|
|
actual := a.pow(exp)
|
|
assert actual.binary_str() == expected
|
|
}
|
|
|
|
result := '66325146064916587705822805477951823674769212922003325230500180789514487101799702287247301347816140714887582527826252837635296749781071351621748491469338347097923896026211183517655658952346069454893422558286798338709431368762851475568899541999504754550056265493269010870696623999709399529395247064542825851568385196637089440522882877102429945439977107582295420418108331098961838419917230847980056560488541780255425015021238743932289115066701337398107639567748102191005710201353615093246958907555634902309636451244444952203735074916066229982498598205421944122042066749035283837586883383420374291325389757869347147357807188516650352693616763867685354382631931356465247637321960345782811272139101785279798666504361229957479336436466489780129445016691164329417001378480690804715301830926348058624'
|
|
|
|
assert big.integer_from_int(324).pow(u32(315)).str() == result
|
|
}
|
|
|
|
fn test_mod_exponentiation() {
|
|
divisor := big.integer_from_int(632)
|
|
assert big.integer_from_int(324).mod_pow(u32(315), divisor) == big.integer_from_int(512)
|
|
|
|
a := big.integer_from_int(65)
|
|
b := big.integer_from_int(2790)
|
|
div := big.integer_from_int(3233)
|
|
|
|
assert a.mod_pow(17, div) == b
|
|
assert b.mod_pow(413, div) == a
|
|
}
|
|
|
|
struct BigModPowTest {
|
|
base string
|
|
exponent string
|
|
modulus string
|
|
expected string
|
|
}
|
|
|
|
const big_mod_pow_test_data = [
|
|
// vfmt off
|
|
BigModPowTest{ // passed to mod_pow
|
|
'23',
|
|
'35',
|
|
'4205',
|
|
'552'
|
|
},
|
|
BigModPowTest{
|
|
'5155371529688',
|
|
'2791323022555160232601405723625177570767523893639864538140315412',
|
|
'108959927459825236754563833',
|
|
'26860526814751021488886966'
|
|
},
|
|
BigModPowTest{ // odd modulus
|
|
'352374589237450928347609812740958719304509123759871239856523745782375908723095729758275893947985713250128357912349123412939358823582385385198351236046127834612374812370491327508137250913279785120956123875610235871239857198203659081236598012735981327096129836712397538257324587324658973246586212305713209851290386517823650983',
|
|
'1435987139846732486843289483294829493285238539385476982375980650172394182703846128975612083751298035612365812378908579834576456739458768754674674758467957697513267415734673649713598712634987126359872685236563875',
|
|
'235091287508475298347528357901372598012305123512513252139683276908769284375274983274732895287478365817326581273509823651087861235876123563725193512827341395182375612384723587131912725187352562171235812387132578235385239913578132684794719844871326571632561325617256983275689175687132487134894717895941563769587165871727358791326578126587261589732165781623578921653625871256781326587132658716237561235612783569812358791263985688921356634756374561398756298576128463875627',
|
|
'169366899917096971139137080261692248176119100321982279129907315595573960531869689311776921667033660828498254917762241531493510090131310371752611041591194730984721766392649610729748330695093443476931010397820703902902374473806912248240019857777647140275706106146415293419050004306619925031697942412075960435433660980502714238024766862370671258678169869169308956145487178274009104771385352022837969419172440632584754050020898915411115587200113298960058827089497449758704',
|
|
},
|
|
BigModPowTest{
|
|
'65963856903485603485069234860923480925798172358172309571298347102836578126398512837409812375712637895612379856123981237510298356120347129803401236571623978561287347129837563453245983475983457439573985398456987356198236481727340813259182735619827356189723658763578623842342348791856178236598273498213492641265929375983589324658972364587869871263587612387568767345727346273647235738786247865198746132879461234613284823467',
|
|
'83272598179813257612837472873648237598405840629839475914921364871236813258573298457912734897123942134273981',
|
|
'5839857294085157278513295172390857198203571235213752396329429342385198326512374982374982394818327590816263059612397512983479812378951235123571239857908674389573485791835127834617823648791263587321501273958734987520983475818586128374612837589734985729073459081628387561982736547958729875923652356138756183576',
|
|
'1473628912328925119498300555459646092229919432628304743927027840523966896206312866878166443381090567655363186687840805386391819767096022910509388879763843632740700147538366282034781700814905320520871339523971198789410048087451530293781098724024347130773477767285944506944257502250353223975013799044669645147',
|
|
},
|
|
BigModPowTest{
|
|
'113242346235324852305823906832570234458325884382848882352385183957109823579028553482572308468203945823946234096234056990567506978059607985823049523458273598234750329857',
|
|
'80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
|
'538232475982347092375235252304678234670293486732980467394932151374571938467459586739087429813752353459823475982375983259823495510986571430996238476587342658172851235761398456398765813459801238751782351252542389712789568712342749837482748292340120120350125012352859821657823501275012365123985761983576123561273561257632958127659327160124712350123571029356123512507123598321797',
|
|
'192406008638594029999856291470760872362212741932343638540342189789173751505083836385843995643278520411152869906156437055678588013127671381619800101872065097151880787029771615331116606406595932983669815757450573569058422413443800383057849205750667577751024330669200452034408252515262931175662782786664172617789499914619948520343146045783354828154425927051367644302499369000252',
|
|
},
|
|
BigModPowTest{ // even modulus
|
|
'235823052395732458137502345873250',
|
|
'9247324572804102889565555777311914057954687482673431192869682151395651003606366864848904841770165182604035932529621174486515688424932060959148379649412557',
|
|
'2176617445861743577319100889181907668374255538511144643224689886235383840957210909013086056401571399717235807266581649606472148410291413364152197364477180887395655483738115072677402235101762521901569820740293149529620419333266262073471054548368736039519702486226506248861060256971802984953561121442680157668000761429988222457090413873973970171927093992114751765168063614761119615476233422096442783117971236371647333871414335895773474667308967050807005509320424799678417036867928316761272274230314067548291133582479583061439577559347101961771406173684378522703483495337037655006751328447510550299250924469288818',
|
|
'442997670902441289693502035236411859724060788065895656400579052337406446773758010436855122951259016429941998670112046510440662262181776245572088822784133641469508278250883828352296420961829921453124482851450238472747959697964344812370952273954391788494014188845640003786259215718720844436373044245757220429613176387487778233231542432645946351180509817097194411903946161272789482180797502735809791321387092632573236334305080001390892058454801700346356574718281589228939135660037060121182304974907075601193595994210348704718150369101358547875357900995290428579291079564736470284970163062216850888677989344123412'
|
|
},
|
|
BigModPowTest{
|
|
'5155342534532472457235424353715296885321784212092346234575235718572938457284759829789708703754094283682345782309123940810923850923745723498672398459023845028309402347698798128209480234598716824503042159',
|
|
'86088201503667039039649712985497870124991029230637396538140315482910296196688861780721773488400937149055855947456947824680518799310618149812585881185273945728945238450238465982768132749812308932579342985729345798328459832591982374981237590923882894732852358383128938192888912389148132163716923461512177401900495710673973552425181964932538140315421936569702910921834517138450159290932430254268769414',
|
|
'274591906405224388599271723580726658164960647214841029141336415219736447718088739565548373811507267740223510760319632557286907774120057322163752385728943578236484780326508234652347012734098132747829056238742677853836742172732148487951998402235107603196866575250296113164460906849287604912497386435248807205228608',
|
|
'191409711082233170599206818399072245570776992384487887400529042633340865718475272702984694979757086140971619519330041885966232600204343618098862571914303534164078578922423233100444505069197147657365390879382972696958855409999020160689093198793125749417593529720182526801136320146027275209623807723638007207345057',
|
|
},
|
|
BigModPowTest{ // power of 2 modulus
|
|
'853475230582304956623462734587234857',
|
|
'583752847502934572695871320598123057810835791832765601237490813250912360591237591247132543095792347598327957137481023974819237887128577123758127912735720912735708362178561027835610235610256231201472309873219800321951',
|
|
'31195165372897259196222538898096203590151924108450147950531565441852619837316692843188389598728651769482088968838700984268947453885587967878549286444999755742573423371025356539077075265986419171772426279084559025861175301940492273427120221755816136975739916983004778387946699939545354293487098252428954036286183995782377175227121587657233553706589448547148066273280603243167958729707736664649187444136702017299877489729451997277875868782399735511520086969969766278182145454186690598629675562422923132555707758646587702550600894625696538109646366308973392363200122154242784576162149305816215109893613161331026672647000825615987247035266514313689413563779184515427920269935280569035788081552413007563772309295149800172031645681720569680154349893907395864528243629654386620034655445226295834594630792819545156798270599481573436039129275439653984521135652249263653985326577886990615665734998585216581730937090703518997669223802429711292740491797911117308280939507973715877108492303860661291987529284719391551256912380499409630332506454532263266457209921483705507359152839264852808182519011100934922492651373859423833024010283468753147686188675294998119637462200763443029190704825719342806119404339670408160210011918981038977425180213726646978883378058838510330816291941879581568740273684084511318422175006728346276489384220596694727036836687670632486602655240593463885077059375085482211864761344849868123074687509143827139683659102930877963676911995751113159944160296419825178911962487549670296207457410515598040046860567719116506974858703739531721991704589155513182996455827177472',
|
|
'20080128881481836026329919458482291336427826856257996902940216961274769492432457342329585911526680598599706497937330675336231322550089070961997878231160797014417182095610964306078005177657705895303701167263611016504813896879268670353690809857529479048652197026092060293580162938995900771157020773980149060390600886988165389386800313399935681668574561849644795370126640258861886083152431680309682414362667647047408205246634496700184520404072535696087062725321498879508195864728319264953502905783599235208616928912295007582161378604427602444176983900856363236858555001132922259491209136145654862306503211818341793436738181575298025051779368026867674815572620689517665845691581156037531328681002192885908572782500210185856071870996928958700199226442991667291661898788475465881534872952976564959204125435567408766407069080824764398534937188392006557445009391997597405999602710062336419706104598663078108578494090878260551511868925451048198114479011315931259263368212342695453474607592164864833976245439378166385649596428707473508482940426102862136582304433403471613967149235623865180698593404828164563801111816849132293956996556247415009648932020221786934682827799748481777622180801590275002765776928805756187584952776044614940158088391767782343033313716059721086499569092199761880797791493764006487948292742803823944731896556184944138299575510183812680359579022267096795084742403276965131310267236257021618824374001979653996305168583849734973984410291953747451176667816227487401602863864660642232048020325795772190251487050535547981550465960228478297407995702324941118877701015321',
|
|
},
|
|
// vfmt on
|
|
]
|
|
|
|
fn test_big_mod_pow() {
|
|
for t in big_mod_pow_test_data {
|
|
a := big.integer_from_string(t.base) or { panic('Could not read decimal') }
|
|
x := big.integer_from_string(t.exponent) or { panic('Could not read decimal') }
|
|
m := big.integer_from_string(t.modulus) or { panic('Could not read decimal') }
|
|
r := big.integer_from_string(t.expected) or { panic('Could not read decimal') }
|
|
assert a.big_mod_pow(x, m) or { panic(err) } == r
|
|
}
|
|
}
|
|
|
|
fn test_gcd() {
|
|
assert big.integer_from_int(0).gcd(big.integer_from_int(0)) == big.zero_int
|
|
assert big.integer_from_int(10).gcd(big.integer_from_int(0)) == big.integer_from_int(10)
|
|
assert big.integer_from_int(0).gcd(big.integer_from_int(-18)) == big.integer_from_int(18)
|
|
assert big.integer_from_int(51).gcd(big.integer_from_int(22)) == big.one_int
|
|
assert big.integer_from_int(98).gcd(big.integer_from_int(56)) == big.integer_from_int(14)
|
|
assert big.integer_from_int(98).gcd(big.integer_from_int(56)) == big.integer_from_int(14)
|
|
|
|
a := big.integer_from_string('67116917544110') or { panic('Could not read decimal') }
|
|
b := big.integer_from_string('60943431483592') or { panic('Could not read decimal') }
|
|
c := big.integer_from_string('6299482') or { panic('Could not read decimal') }
|
|
assert a.gcd(b) == c
|
|
}
|
|
|
|
fn test_factorial() {
|
|
f5 := big.integer_from_u64(5).factorial()
|
|
assert f5.hex() == '78'
|
|
f100 := big.integer_from_u64(100).factorial()
|
|
assert f100.hex() == '1b30964ec395dc24069528d54bbda40d16e966ef9a70eb21b5b2943a321cdf10391745570cca9420c6ecb3b72ed2ee8b02ea2735c61a000000000000000000000000'
|
|
}
|
|
|
|
fn test_inc_and_dec() {
|
|
mut a := big.integer_from_int(2)
|
|
mut b := big.integer_from_int(3)
|
|
mut c := big.integer_from_int(4)
|
|
|
|
a.inc()
|
|
c.dec()
|
|
assert a == b
|
|
assert b == c
|
|
}
|
|
|
|
fn test_lshift() {
|
|
assert big.integer_from_int(45).lshift(2) == big.integer_from_int(45 * 4)
|
|
assert big.integer_from_int(45).lshift(3) == big.integer_from_int(45 * 8)
|
|
assert big.integer_from_int(45).lshift(4) == big.integer_from_int(45 * 16)
|
|
assert big.integer_from_int(45).lshift(5) == big.integer_from_int(45 * 32)
|
|
assert big.integer_from_u64(0xabcedabcde).lshift(20) == big.integer_from_u64(0xabcedabcde00000)
|
|
assert big.integer_from_bytes([u8(1), 1, 1]).lshift(56) == big.integer_from_bytes([
|
|
u8(1),
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
])
|
|
}
|
|
|
|
fn test_rshift() {
|
|
assert big.integer_from_int(45).rshift(3) == big.integer_from_int(5)
|
|
assert big.integer_from_int(0x13374956).rshift(16) == big.integer_from_int(0x1337)
|
|
assert big.integer_from_bytes([
|
|
u8(1),
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
]).rshift(56) == big.integer_from_bytes([u8(1), 1, 1])
|
|
}
|
|
|
|
fn test_isqrt() {
|
|
for i in 0 .. 1000 {
|
|
a := big.integer_from_int(i)
|
|
b := big.integer_from_int(i * i)
|
|
assert b.isqrt() == a
|
|
}
|
|
values := [
|
|
'314',
|
|
'213149',
|
|
'2198614',
|
|
'318014',
|
|
'1000000000',
|
|
'1000131039410',
|
|
'2148170394871039847019843349714981',
|
|
]
|
|
for value in values {
|
|
a := big.integer_from_string(value) or { panic('Cannot read from decimal') }
|
|
b := a * a
|
|
assert b.isqrt() == a
|
|
}
|
|
}
|
|
|
|
fn test_bitwise_ops() {
|
|
a := big.integer_from_int(1).lshift(512)
|
|
b := a - big.one_int
|
|
assert a.bitwise_and(b) == big.zero_int
|
|
assert b.bitwise_xor(b) == big.zero_int
|
|
assert b.bitwise_or(b) == b
|
|
assert b.bitwise_and(b) == b
|
|
assert b.bitwise_not() == big.zero_int
|
|
}
|
|
|
|
fn test_get_bit() {
|
|
x := big.integer_from_int(42)
|
|
assert x.get_bit(0) == false
|
|
assert x.get_bit(1) == true
|
|
assert x.get_bit(2) == false
|
|
assert x.get_bit(3) == true
|
|
assert x.get_bit(4) == false
|
|
assert x.get_bit(5) == true
|
|
assert x.get_bit(10) == false
|
|
|
|
values := ['1001001001001010010010100100100101011101001001010',
|
|
'1111111111111111111111111111111111111111111111111',
|
|
'0000000000000000000000000000000000000000010000', '1110010', '0001001']
|
|
for value in values {
|
|
a := big.integer_from_radix(value, 2) or { panic('Could not read binary') }
|
|
bits := []bool{len: value.len, init: value[value.len - 1 - index] == `1`}
|
|
for i in 0 .. value.len {
|
|
assert a.get_bit(i) == bits[i]
|
|
}
|
|
}
|
|
}
|
|
|
|
fn test_set_bit() {
|
|
mut a := big.integer_from_int(32)
|
|
a.set_bit(1, true)
|
|
assert a.int() == 34
|
|
a.set_bit(1, false)
|
|
a.set_bit(3, true)
|
|
assert a.int() == 40
|
|
a.set_bit(50, true)
|
|
assert a == big.one_int.lshift(50) + big.integer_from_int(40)
|
|
b := a
|
|
a.set_bit(100, false)
|
|
assert a == b
|
|
}
|
|
|
|
fn test_bit_len() ? {
|
|
assert big.zero_int.bit_len() == 0
|
|
assert big.one_int.bit_len() == 1
|
|
|
|
assert big.integer_from_u32(0xffffffff).bit_len() == 32
|
|
|
|
assert big.one_int.lshift(1239).bit_len() == 1240
|
|
|
|
mut num := big.integer_from_string('4338476092346017364013796407961305761039463198075691378460917856')!
|
|
assert num.bit_len() == 212
|
|
for num.bit_len() > 0 {
|
|
num = num.rshift(8)
|
|
assert true
|
|
}
|
|
}
|
|
|
|
struct ModInverseTest {
|
|
value string
|
|
modulus string
|
|
}
|
|
|
|
const mod_inverse_test_data = [
|
|
ModInverseTest{'1234567', '458948883992'},
|
|
ModInverseTest{'239487239847', '2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919'},
|
|
]
|
|
|
|
fn test_mod_inverse() ? {
|
|
for t in mod_inverse_test_data {
|
|
a := big.integer_from_string(t.value) or { panic('Could not read decimal') }
|
|
m := big.integer_from_string(t.modulus) or { panic('Could not read decimal') }
|
|
r := a.mod_inverse(m) or { panic('No multiplicative inverse in ring Z/mZ') }
|
|
assert (r * a) % m == big.one_int
|
|
}
|
|
}
|