diff --git a/vlib/math/big/big_test.v b/vlib/math/big/big_test.v index ae7e59b34d..a79a4e09c6 100644 --- a/vlib/math/big/big_test.v +++ b/vlib/math/big/big_test.v @@ -236,6 +236,11 @@ const mul_test_data = [ '172750769107109861232750661741561572021207635860888814481781323903637921618217893620438648685692072759912890797284948206448457977080536627892119852493829355756035584640064060706092098984542716937323104336194056741403356304500304286336281585594296381344018535478383343176463402322692068381151973870461499748949', '27276318124492212465432029043652584179286098914879267159076000142724287743892530142734241126306064189405321580796475224876708675570413592358715948396724932685085972846389975012793388131866028332508690735727488135870026351955805826642739703000986587467280495743559787380135296551334471419857554510187338555406214731430906002559624746468831645485763335047438526317636794466414295301915951975626967409997005043887959717124157434636781107429998249363525957258509402650503217872035874896065023377356660153975719637017472701236397203173555796145677008784279961849944450443054513670798899182054747598702569678446196470652067', }, + MulTest{ + '164171010688258216356020741663906501410127235530735881272116103087925094171390144280159034536439457734870419127140401667195510331085657185332721089236401193044493457116299768844344303479235489462436380672117015123283299131391904179287678259173308536738761981139958654880852234908448338817289014166774169869251339379828599748492918775437864739032217778051333882990074116246281269364933724892342134504702491040016637557429810893780765197418589477584716543480995722533317862352141459217781316266211186486157019262080414077670264642736018426998113523445732680856144329876972273300703392584997729207197971083945700345494092400147186997307012069454068489589035676979448169848060836924945824197706493306108258511936030341393221586423523264452449403781993352421885094664052270795527632721896121424813173522474674395886155092203404036730748474781710715745446135468098139831824083259647919175273503681561172684624283384438504776503000432241604550454374116320822227191911322123484085063926350606342197146407841178028071147192533942517270553513988142925976090769695456221159699052583533011331652079347093098173086975483539274464023357456484465482927479569437320368592222760278170306076733438801098370797675711274671054970711442158930561684343135774118741612806419906031631601266266528538520924083161856865743302334249701407315310271018388258886432135273827859691733059369978643041918967442197313534697497404277350224866705804878433671262763482023400349043259178916572687989162930903779045078287573241909420120175442471703679516781197223112216572138640838928909745860699538278329256643602865002960800914563144124971099443335826150972157276451120655954671045954561868041854882824297821929166520068974703653272620867577906523992874996338253216963333346753434848676176334066388995978444434383568257588867823277644840815468397633199054967729800149549182806977698239412258835996851311070873503482289001486370524332318228425883088614099902710492272286924686293234474771490822760225994669314033129796588388559938376504519357876526207739824571643922272657401623465041482584188509253569882124046470363144411921518246416624724749905231440644997507666770400152259424985923818812142693481946120458476848688265618957991911827715393356088636270325443851034622105141544646198235918882925122792559855912557079094394123423520644892444598598382078381161104113085486556201098925110067360753401358261464776577606903832478339589245804354508579087454162252694910844773344482611021149046116480354455617601305942523594483024855696034938579749778676423303176347347340888151177304988777650344799235158668778873655761927959467569060076066072141671787427033055911592569177110108260910246683849221598266832809998266670667496151841679241795933186305511292585313329789010406328741552521015186335892928959457352185210813706585793586655431835891916663865991383787060819588518563583863708252865070444576697776679046010833807029569591348215890550165411598509381309327227435222644862430930229016269154648515310921604137823785068951323692515705020432705359040238577897883574592171044699141069510442621429004794500509511164629247377310724138812839948146966014875865442002316316147115822535873869666457623686808443012969266429403451480342554038729339523589198931048749201138547833872346632292790389972480203315668048506830004489963474939936865962713230081702234756288583317445417488060638503911953948752192577969339481782002204627524507475657361770841692340030079253938076572038965695553701689311893564901777963171410092537042768312674959903738742767629763355851912035193112645928966314357454371342743116099157217558740986764594149942742163671005121600737607969017218138001028636328155384350303672943227090754877409301936853603040377097713234172254531565106020239802368', + '164171010688258216356020741663906501410127235530735881272116103087925094171390144280159034536439457734870419127140401667195510331085657185332721089236401193044493457116299768844344303479235489462436380672117015123283299131391904179287678259173308536738761981139958654880852234908448338817289014166774169869251339379828599748492918775437864739032217778051333882990074116246281269364933724892342134504702491040016637557429810893780765197418589477584716543480995722533317862352141459217781316266211186486157019262080414077670264642736018426998113523445732680856144329876972273300703392584997729207197971083945700345494092400147186997307012069454068489589035676979448169848060836924945824197706493306108258511936030341393221586423523264452449403781993352421885094664052270795527632721896121424813173522474674395886155092203404036730748474781710715745446135468098139831824083259647919175273503681561172684624283384438504776503000432241604550454374116320822227191911322123484085063926350606342197146407841178028071147192533942517270553513988142925976090769695456221159699052583533011331652079347093098173086975483539274464023357456484465482927479569437320368592222760278170306076733438801098370797675711274671054970711442158930561684343135774118741594506702833147396758825015850042983343690345185995956235143825771620543546030664562647854656431302644574119873820215595718618624485232422006575550007068883734241454686368856734496265385908809403972494685137741122866896719678053937285818409751670320140501843039224040735870096889596273419106389103662095318937990625980136711988237421962315266686856089505981438440850638067589321141759499017023839596858455548192000140085142294166987063499024792681334843159790936321351919859758669569200541507612099780909705198902176026219872201715422096090343686272984351441594569506778041062663266799342793856313801540959815845788584759033248828248561586450271172777240971795656082001848115815260930521663167480173886064019118572778281516735157779555888167787064432558595410843987446497881666288423233170060413025924629950477303342180149398926073618582715358742250388958231281694757980523791263699450732952325727664209947786063982561775327638504516918570101319391698412388607603742484414748268389669129118026878969735782286841116842656410574647607524418900720328045377993386279808768990376289424757351052369393977137871998119168898493037938756635621557623138404459266598837784229325799838782026060481496865561757031839002257091802876949248392744175669112242088439883248336310597001257385980776961529351198877747193531054956881808332177946751404038228718567911769630971553915410012677600002457982207465176670752102117002773980548089696530972476439694599881281812973217265853884727906535479745854085338851105144585481994156206497436745899944877732531412541279014300324594890623941145509856940982863769834430048120562966797907114102689879364945689860493474954538422367719507882513166051007352994068319251450666676648368200564329382998758875760414259654004977261309988267319806354856051784553990936610634733375984159028722378614984450255386315585631994503350002142910493190254825610707400589976364985748467955131077971641882672895854571236368282811336220769174784720113331269084746524204124263475054112841630933586166195036115696469686075600480420563557567616835633252622327172811002146392754445051182169805284630259703542633955126179520113059629914229833688535925729676778028406897316106101038469119090984567152591962365415039646394591503830797626339246986057077758611413664914168745375266786298141171496573941614387744125843685677063619782918759823106021054037757857761587472240835040580447360544029064930412569943169729238102162312218687930203068055400275795180972382856696655279408212344832', + '26952120750404193513632261861396278924079113968766952876432881795989952773064717517023547582462602935861988343151554953944136541732655742330344989715209032364790613993477992341015538315419979331157634679343214071675070272395846031050203990104416181306504888110677311345026982121311496900694993981896839097431416270736937100764483879691603475885150790913382009428152150677416837810025855012562604552257734907950240215423643722920841320085070969159836995287070087420490979348953287935459923512005502958342051104035727152157034501872596309497091807346831534602296739237000381981019425624127797257428795930313308723276992913170326233270996326474955890573590440983689956983091520247822856749856820965867151327989623777624602572912120388034513739443184281299447784120922392413596992920178190422947851327532150609341086404785058445916781202298840013744572277995937219260793226200101547804156066660550285603334189758481973110179753448682028957898790867330285566013316232853414644614046984553042091064852269504063338721280356430534362274115530450091697615931104386348165503547977506883150962456655568148350174378900644954808571193522853482254105207391043768826214265699942108058612042527547825232804870924409920355692212828892863846898524675998477589207679627913426446911721636181076105773289579082001255169089756739791438011116518233115849097737157581281333580664166552977845960545954723805566039806442684931440076772740156280813903751559368611983279879027372690912528122650045008005005809343307282215075359167739564986702643979470063161755939428463215178956585736792740691950620097366581157756475030693880639628028957564717506748388201460479934997075131639772156110050292383682801311501912272752251146034896908669589822188561182421548567626442405902050737934260444280400808091464891948286615235680364697810945744811260658644380752469468836186050949182213434987088443266923626493072368804684047208628736100483353498142871019538184448301514555455010870017957531222712151602595676715076786235173047351215526266074242232161952576329350969226099826143111340343868870776877764034804728697456714672752694955488362666813205601556848124569582733894829010185412078368158205633679452772740325245039148128091807268340159268190332390713116057956368833309632262724886914292004136532397863207156676423356271923268788997230183054983059464198418861749695567960894202252252428985718482550976909314126235919259431415097735142937056722180867395933758463429791251108228353506370378738883720057492392037062821199203576669507492379745663106636034141603529648250152072791795482426726847812075334671757150236305208856903602455132348260148117295696786160355352582815449613577389346464373705124445269845460300288087567879763606935329100064117928257129252417621314419004760295848797915067238834947059440036300737231196862875219470421825117891378677739697421559711211629645270252793111734441650294153890976657767935712751203970943075020427006224205578839537057762673700366813557873687195377885524377489413547417966336038733668837250885045180743821511112631400632585671166459524266991554490866854531282544830112396457787644133453547856918930267859252150666726303020818421604707816925326976802969324733095651243384448217063086179891052711416102828902776777800575003340232129652988185822691921315007186111366967324619073300429154583580635182127032049900544244545877614607444202238535981253295792569233858056209849105015633097827466842007884364230830675959668956019416191744176273361652039495912566102173045501639186081539123978052600644656251454292831580163089995965156233995220589648586920484863866827793184837626067415823731083525652620669832827156376121692170869677070642914646861380391369585780688443200170048259608955804667153883910612516726213308610915717138614799386761520965945787127839457050969293052466264047315624091114595035121852015667880592176144651859725075932198615571560789839214709994586617323564833873826223285742144757371088512442294526818322560870149959071359649404990835260598668977487201391641043166495938834420563709960733615372690590955459181016613349571195006677610310002583941425268713657639502302803341273127570270640425767468628392567564760410981218311866726323025932458512505099003963583291824276379468077888588991880595511218503954977878133134979730471068872384092380589477389509938459514027145041834618844513493123450381617418440276701681286746028194024840212540436669375081186633501602178611269022208447096228181869444834504966501924555225696054544947206129816153131308335205416097203955681491548390262577040628244205265357720428630108475623343162491975302169920528121320528957901449810640978556725429813475199342692168963973253340960441915172016945686990705723008204739699363476332881074090180937394437542797628356677310043665712274506350688717886042284479518244686074959646346047403964455232532814174782630231938398909137493083955097318419378310781800343570308447561516825855786344789474629888793013470201743911722403671905785779851302951521921132715319986089541487934077691955482266807220271193537633086592882151150308693220488018175636884029840866394624403205565579590057527962012921266347225994979367899377208497520620936129908581263574751820276075465651145907167542331242133958382307096322911199736769597988300118662979347125708251012250130548531693570552624584154336043221663856927311119801227444935344728459975797444666683477304304565466799558739413214142745624868296093021840548408108284133874907162149854774961961427584595743817051618155142326168647056011338867898006827285744302239476116375199315336737573543155497019204012481403238908281049354957812260853879180351380194157400769663673812155953436673765910376334004666292477853537867662871238308187390899260490523967153636265268799510554541618376865163856548884752741759505726850279884726397853487909152060637968595571006650653455483279642541396711835514962791318266675127774800981248980551879698727644799613397656625541551710897466658456664422128462459317246909558705620849301799110441260238810244824269149895725661100522155256385441891068194026627970889014197024276645561363292170822142584766005537947377013084637179443743260546363616665310256887925165785266204306690292438898120371494508505316637646069386959561273837790540798539752405236061152352862816042538854769587005440351339714760090162072113995509567157488906861196780594046290353099182073183613284430701084935002839752590550751562907742484518683997180734853476722099449673240962819930529932444168559077769000316841734766444816028799535673071675338228964188255114321594468218878208314581807542614629089851073096897231513024947406152399667303062490554608082062728352653787956017464487187973175435276455438354935592052167112322604392662045767918388805257954592744043455097699580368600917403323813475962872048741029144684051016765558592279266497621805828487724797698180628421670657972769274936562693990701778769245014493873070983648996255754271338304680209337765482626114795132189802426201979332758083613325788234699620295352040580332040824799909539814474800169863581704020475493961264321714819246847318743352835136103926806505544549908267250237738233812823453475627188921057250941636157067180515026083437510656852380716390684473449594460330458925616289093713297296170931498389442936383986610935498709801397585871717062958941748357812271705754879617475612535882476104585221272969815038430888621530428764313341480567925789660550772911037726992636455102674850865267643942347482222424003636645592271860976670047577546162176' + } ] // vfmt on diff --git a/vlib/math/big/special_array_ops.v b/vlib/math/big/special_array_ops.v index f5ffb3ceea..c374e7d052 100644 --- a/vlib/math/big/special_array_ops.v +++ b/vlib/math/big/special_array_ops.v @@ -13,6 +13,17 @@ fn shrink_tail_zeros(mut a []u32) { } } +@[direct_array_access; inline] +fn (i &Integer) shrink_tail_zeros() { + mut alen := i.digits.len + for alen > 0 && i.digits[alen - 1] == 0 { + alen-- + } + unsafe { + i.digits.len = alen + } +} + // suppose operand_a bigger than operand_b and both not null. // Both quotient and remaider are already allocated but of length 0 // TODO: the manualfree tag here is a workaround for compilation with -autofree. Remove it, when the -autofree bug is fixed. @@ -108,8 +119,8 @@ fn karatsuba_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage // thanks to the base cases we can pass zero-length arrays to the mult func half := imax(operand_a.len, operand_b.len) / 2 - a_l := unsafe { operand_a[0..half] } - a_h := unsafe { operand_a[half..] } + mut a_l := unsafe { operand_a[0..half] } + mut a_h := unsafe { operand_a[half..] } mut b_l := []u32{} mut b_h := []u32{} if half <= operand_b.len { @@ -119,6 +130,10 @@ fn karatsuba_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage b_l = unsafe { operand_b } // b_h = []u32{} } + shrink_tail_zeros(mut a_l) + shrink_tail_zeros(mut a_h) + shrink_tail_zeros(mut b_l) + shrink_tail_zeros(mut b_h) // use storage for p_1 to avoid allocation and copy later multiply_digit_array(a_h, b_h, mut storage) @@ -171,6 +186,7 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3 1 } } + a0.shrink_tail_zeros() a1 := Integer{ digits: unsafe { operand_a[k..k2] } signum: if operand_a[k..k2].all(it == 0) { @@ -179,6 +195,7 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3 1 } } + a1.shrink_tail_zeros() a2 := Integer{ digits: unsafe { operand_a[k2..] } signum: 1 @@ -201,6 +218,7 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3 signum: 1 } } + b0.shrink_tail_zeros() b1 = Integer{ digits: operand_b[k..] signum: 1 @@ -212,12 +230,14 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3 signum: 1 } } + b0.shrink_tail_zeros() if !operand_b[k..k2].all(it == 0) { b1 = Integer{ digits: operand_b[k..k2] signum: 1 } } + b1.shrink_tail_zeros() b2 = Integer{ digits: operand_b[k2..] signum: 1