fastnum 0.7.4

Fast decimal numbers library
Documentation
use core::str::from_utf8_unchecked;

use crate::{
    bint::UInt,
    decimal::{
        dec::{intrinsics::Intrinsics, parse, ControlBlock, ExtraPrecision},
        signals::Signals,
        Context, Decimal, ParseError, Sign,
    },
    utils::err_msg,
};

type D<const N: usize> = Decimal<N>;

pub(crate) struct Consts<const N: usize>;

impl<const N: usize> Consts<N> {
    pub(crate) const E: D<N> = make_const(E);

    pub(crate) const PI: D<N> = make_const(PI);
    pub(crate) const TAU: D<N> = make_const(TAU);
    pub(crate) const FRAC_1_PI: D<N> = make_const(FRAC_1_PI);
    pub(crate) const FRAC_2_PI: D<N> = make_const(FRAC_2_PI);
    pub(crate) const FRAC_PI_2: D<N> = make_const(FRAC_PI_2);
    pub(crate) const FRAC_PI_3: D<N> = make_const(FRAC_PI_3);
    pub(crate) const FRAC_PI_4: D<N> = make_const(FRAC_PI_4);
    pub(crate) const FRAC_PI_6: D<N> = make_const(FRAC_PI_6);
    pub(crate) const FRAC_PI_8: D<N> = make_const(FRAC_PI_8);
    pub(crate) const FRAC_2_SQRT_PI: D<N> = make_const(FRAC_2_SQRT_PI);

    pub(crate) const LN_2: D<N> = make_const(LN_2);
    pub(crate) const LN_10: D<N> = make_const(LN_10);

    pub(crate) const LOG2_E: D<N> = make_const(LOG2_E);
    pub(crate) const LOG10_E: D<N> = make_const(LOG10_E);

    pub(crate) const SQRT_2: D<N> = make_const(SQRT_2);
    pub(crate) const FRAC_1_SQRT_2: D<N> = make_const(FRAC_1_SQRT_2);

    pub(crate) const LOG10_2: D<N> = make_const(LOG10_2);
    pub(crate) const LOG2_10: D<N> = make_const(LOG2_10);

    pub(crate) const C_180: D<N> = D::new(
        UInt::from_digit(180),
        ControlBlock::new(
            0,
            Sign::Plus,
            Signals::empty(),
            Context::default(),
            ExtraPrecision::new(),
        ),
    );
}

const E: &str               = "2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354";

const PI: &str              = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989";
const TAU: &str             = "6.2831853071795864769252867665590057683943387987502116419498891846156328125724179972560696506842341359642961730265646132941876892191011644634507188162569622349005682054038770422111192892458979098607639288576219513318668922569512964675735663305424038182912971338469206972209086532964267872145204982825474491740132126311763497630418419256585081834307287357851807200226610610976409330427682939038830232188661145407315191839061843722347638652235862102370961489247599254991347037715054497824558763660238982596673467248813132861720427898927904494743814043597218874055410784343525863535047693496369353388102640011362542905271216555715426855155792183472743574429368818024499068602930991707421015845593785178470840399122242580439217280688363196272595495426199210374144226999999967459560999021194634656321926371900489189106938166052850446165066893700705238623763420200062756775057731750664167628412343553382946071965069808575109374623191257277647075751875039155637155610643424536132260038557532223918184328403978";
const FRAC_1_PI: &str       = "0.3183098861837906715377675267450287240689192914809128974953346881177935952684530701802276055325061719121456854535159160737858236922291573057559348214633996784584799338748181551461554927938506153774347857924347953233867247804834472580236647602284453995114318809237801738053479122409788218738756881710574461998928868004973446954789192217966461935661498123339729256093988973043757631495731339284820779917482786972199677361983999248857511703423577168622350375343210930950739760194789207295186675361186049889932706106543135510064406495556327943320458934962391963316812120336060719962678239749976655733088705595101400324813551287776991426217602443987522953627555294757812661360929159569635226248546281399215500490005955197141781138055935702630504200326354920418496232124811229124062929681784969183828704231508151124017430532136044343182815149491654451954925707997503106587816279635448187165095941466574380813999518153154156986940787179656174346851280733790233250914118866552625373000522454359423064225199009";
const FRAC_2_PI: &str       = "0.6366197723675813430755350534900574481378385829618257949906693762355871905369061403604552110650123438242913709070318321475716473844583146115118696429267993569169598677496363102923109855877012307548695715848695906467734495609668945160473295204568907990228637618475603476106958244819576437477513763421148923997857736009946893909578384435932923871322996246679458512187977946087515262991462678569641559834965573944399354723967998497715023406847154337244700750686421861901479520389578414590373350722372099779865412213086271020128812991112655886640917869924783926633624240672121439925356479499953311466177411190202800649627102575553982852435204887975045907255110589515625322721858319139270452497092562798431000980011910394283562276111871405261008400652709840836992464249622458248125859363569938367657408463016302248034861064272088686365630298983308903909851415995006213175632559270896374330191882933148761627999036306308313973881574359312348693702561467580466501828237733105250746001044908718846128450398017";
const FRAC_PI_2: &str       = "1.5707963267948966192313216916397514420985846996875529104874722961539082031431044993140174126710585339910740432566411533235469223047752911158626797040642405587251420513509692605527798223114744774651909822144054878329667230642378241168933915826356009545728242834617301743052271633241066968036301245706368622935033031577940874407604604814146270458576821839462951800056652652744102332606920734759707558047165286351828797959765460930586909663058965525592740372311899813747836759428763624456139690915059745649168366812203283215430106974731976123685953510899304718513852696085881465883761923374092338347025660002840635726317804138928856713788948045868185893607342204506124767150732747926855253961398446294617710099780560645109804320172090799068148873856549802593536056749999991864890249755298658664080481592975122297276734541513212611541266723425176309655940855050015689193764432937666041907103085888345736517991267452143777343655797814319411768937968759788909288902660856134033065009639383055979546082100994";
const FRAC_PI_3: &str       = "1.0471975511965977461542144610931676280657231331250352736583148641026054687620696662093449417807056893273826955044274355490312815365168607439084531360428270391500947009006461737018532148743163183101273214762703252219778153761585494112622610550904006363818828556411534495368181088827377978690867497137579081956688687718627249605069736542764180305717881226308634533371101768496068221737947156506471705364776857567885865306510307287057939775372643683728493581541266542498557839619175749637426460610039830432778911208135522143620071316487984082457302340599536479009235130723920977255841282249394892231350440001893757150878536092619237809192632030578790595738228136337416511433821831951236835974265630863078473399853707096739869546781393866045432582571033201729024037833333327909926833170199105776053654395316748198184489694342141741027511148950117539770627236700010459462509621958444027938068723925563824345327511634762518229103865209546274512625312506525939525935107237422688710006426255370653030721400663";
const FRAC_PI_4: &str       = "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497";
const FRAC_PI_6: &str       = "0.5235987755982988730771072305465838140328615665625176368291574320513027343810348331046724708903528446636913477522137177745156407682584303719542265680214135195750473504503230868509266074371581591550636607381351626109889076880792747056311305275452003181909414278205767247684090544413688989345433748568789540978344343859313624802534868271382090152858940613154317266685550884248034110868973578253235852682388428783942932653255153643528969887686321841864246790770633271249278919809587874818713230305019915216389455604067761071810035658243992041228651170299768239504617565361960488627920641124697446115675220000946878575439268046309618904596316015289395297869114068168708255716910915975618417987132815431539236699926853548369934773390696933022716291285516600864512018916666663954963416585099552888026827197658374099092244847171070870513755574475058769885313618350005229731254810979222013969034361962781912172663755817381259114551932604773137256312656253262969762967553618711344355003213127685326515360700332";
const FRAC_PI_8: &str       = "0.3926990816987241548078304229099378605246461749218882276218680740384770507857761248285043531677646334977685108141602883308867305761938227789656699260160601396812855128377423151381949555778686193662977455536013719582416807660594560292233478956589002386432060708654325435763067908310266742009075311426592155733758257894485218601901151203536567614644205459865737950014163163186025583151730183689926889511791321587957199489941365232646727415764741381398185093077974953436959189857190906114034922728764936412292091703050820803857526743682994030921488377724826179628463174021470366470940480843523084586756415000710158931579451034732214178447237011467046473401835551126531191787683186981713813490349611573654427524945140161277451080043022699767037218464137450648384014187499997966222562438824664666020120398243780574319183635378303152885316680856294077413985213762503922298441108234416510476775771472086434129497816863035944335913949453579852942234492189947227322225665214033508266252409845763994886520525249";
const FRAC_2_SQRT_PI: &str  = "1.1283791670955125738961589031215451716881012586579977136881714434212849368829868289734873204042147268860566958127234147033798629896523257327309790400355379865856752741191968795207049287004359451424231604915456404411090170543464332444169266162227990255269089720461364753818374903174932317026021327967155439987546683207155977523334881524660787604327012032872433924701009166250638937589133125766516310432488690977314063797548617635563658967789502170018369170684432635651786705036660240492451244474498945400677948625285993188527008566089807266316078753919712163186756584411147658475764631584662115239295549365061803431236161190444592352649307180801706885897250057894784328362385486195484511397575915580997496382738744793841457212668495359398972191775260872674529117575030861618688394769665769827583507237913270184826978506176607899308116821145082965496469503494840187939766833554297711783356674789971831633002753719773724087928258145738579276147546534622368573576042310497324379438177936150629902402949106";

const LN_2: &str            = "0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875420014810205706857336855202357581305570326707516350759619307275708283714351903070386238916734711233501153644979552391204751726815749320651555247341395258829504530070953263666426541042391578149520437404303855008019441706416715186447128399681717845469570262716310645461502572074024816377733896385506952606683411372738737229289564935470257626520988596932019650585547647033067936544325476327449512504060694381471046899465062201677204245245296126879465461931651746813926725041038025462596568691441928716082938031727143677826548775664850856740776484514644399404614226031930967354025744460703080960850474866385231381816767514386674766478908814371419854942315199735488037516586127535291661000710535582498794147295092931138971559982056543928717000721808576102523688921324497138932037843935308877482597017155910708823683627589842589185353024363421436706118923678919237231467232172053401649256872747782344535347";
const LN_10: &str           = "2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978";

const LOG2_E: &str          = "1.4426950408889634073599246810018921374266459541529859341354494069311092191811850798855266228935063444969975183096525442555931016871683596427206621582234793362745373698847184936307013876635320155338943189166648376431286154240474784222894979047950915303513385880549688658930969963680361105110756308441454272158283449418919339085777157900441712802468483413745226951823690112390940344599685399061134217228862780291580106300619767624456526059950737532406256558154759381783052397255107248130771562675458075781713301935730061687619373729826758974156238179835671034434897506807055180884865613868329177321829349139684310593454022025186369345262692150955971910022196792243214334244941790714551184993859212216753653113007746327672064612337411082119137944333984805793109128776096702003757589981588518061267880997609562525078410248470569007687680584613278654747820278086594620609107490153248199697305790152723247872987409812541000334486875738223647164945447537067167595899428099818267834901316666335348036789869448";
const LOG10_E: &str         = "0.4342944819032518276511289189166050822943970058036665661144537831658646492088707747292249493384317483187061067447663037336416792871589639065692210646628122658521270865686703295933708696588266883311636077384905142844348666768646586085135561482123487653435434357317253835622281395603048646652366095539377356176323431916710991411597894962993512457934926357655469077671082419150479910989674900103277537653570270087328550951731440674697951899513594088040423931518868108402544654089797029863286828762624144013457043546132920600712605104028367125954846287707861998992326748439902348171535934551079475492552482577820679220140931468164467381030560475635720408883383209488996522717494541331791417640247407505788767860971099257547730046048656049515610057985741340272675201439247917970859047931285212493341197329877226463885350226083881626316463883553685501768460295286399391633510647555704050513182342988874882120643595023818902643317711537382203362634416478397146001858396093006317333986134035135741787144971453";

const SQRT_2: &str          = "1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488472";
const FRAC_1_SQRT_2: &str   = "0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207863675069231154561485124624180279253686063220607485499679157066113329637527963778999752505763910302857350547799858029851372672984310073642587093204445993047761646152421543571607254198813018139976257039948436266982731659044148203103076291761975273728751438799808649177876101687659285056771873017042494235801934499853495024075152720138951582271239115342464684593107902892315557983343565065078092844936186176442546324306247488577109167102142843030073412360385717927437077828534838826860113242723507929400810379237461328613001042792233260729199446972185463295900155694123234078541315050297429352001593240171097448639145320522536318440656869927628058661020122545613850113470563786813640247869054483752009184934184225362899682364530381498470690237827411864498590163401237210314634562429526090502229921075295560124720670864265739052901801685538654591434657355085555841958290863444709879358291076064114759244236";

const LOG10_2: &str         = "0.3010299956639811952137388947244930267681898814621085413104274611271081892744245094869272521181861720406844771914309953790947678811335235059996923337046955750645029642541934026618197343116029435011839028981785826171544395318619290463538846995202393108496124625404002633125946214788458473182826726839823261965427935076313175483509271389649469177857689180507900075995480878154597145850319648776261224922908291181909514989971716198604776765000678205179125573286286683420004029205098370845722248954942975621497072446597086136896092219094827612143914965282351678264923148040277462432441633115387382593038830393806332161302390518805821319156854616929053015051319269853784884187183200657535694683929717421320109058968908505856246409872183968766485398562351612773026389278782608498366810303084314155608139436176745488566634245381237339324224695943490602120445042968274606884785461156847684106437979500465969917745657540864018464079456529544341077408293999745400737217016801948890554856910694003754116899634157";
const LOG2_10: &str         = "3.3219280948873623478703194294893901758648313930245806120547563958159347766086252158501397433593701550996573717102502518268240969842635268882753027729986553938519513526575055686430176091900248916669414333740119031241873751097158664675401791896558067358307796884327258832749925224489023835599764173941379280097727566863554779014867450578458847802710422545609722346579569554153701915764117177924716513500239211271473393614407233972115748510070949878916588808313221948067932982323259311950671399507837003367342480706635275008406917626386253546880153686216184188608589948353813214998930270441792078659226018229653715753672396606951164868368466238585084860629905426994692791162732061340064467048476340704373523367422128308967036457909216772190902142196214245744465852453594844881548345925142954093735390654944863277929842429159118113116329812576945019815750379218553848782035516019737827728888175987433286607271239382520221333280525512488274344488424531654650612414891822867932526642928116599228516273450821";

#[inline]
const fn make_const<const N: usize>(str: &str) -> D<N> {
    match parse_const(str.as_bytes(), Intrinsics::<N>::MAX_CLENGTH) {
        Ok(d) => d,
        Err(_) => match parse_const(str.as_bytes(), Intrinsics::<N>::MAX_CLENGTH - 1) {
            Ok(d) => d,
            Err(_) => {
                panic!(err_msg!("cannot parse decimal const"))
            }
        },
    }
}

#[inline]
const fn parse_const<const N: usize>(buf: &[u8], len: u32) -> Result<D<N>, ParseError> {
    if (len as usize) < buf.len() {
        let (left, right) = buf.split_at(len as usize + 1);
        let res = parse::from_slice(left, Context::default());
        match res {
            Ok(mut res) => {
                res.cb.set_extra_precision(parse_extra_precision(right));
                Ok(res)
            }
            Err(e) => Err(e),
        }
    } else {
        parse::from_slice(buf, Context::default())
    }
}

#[inline]
const fn parse_extra_precision(buf: &[u8]) -> ExtraPrecision {
    const EXTRA_PRECISION_DIGITS: usize = ExtraPrecision::EXTRA_PRECISION_DIGITS as usize;

    if buf.len() > EXTRA_PRECISION_DIGITS {
        parse_extra_precision_buf(buf.split_at(EXTRA_PRECISION_DIGITS).0)
    } else {
        parse_extra_precision_buf(buf)
    }
}

#[inline]
const fn parse_extra_precision_buf(buf: &[u8]) -> ExtraPrecision {
    let digits;

    let len = buf.len() as u32;

    if buf.is_empty() {
        digits = 0;
    } else {
        #[allow(unsafe_code)]
        let src = unsafe { from_utf8_unchecked(buf) };

        match u64::from_str_radix(src, 10) {
            Ok(d) => digits = d,
            Err(_) => {
                panic!(err_msg!(
                    "cannot parse decimal const extra precision digits"
                ));
            }
        }
    }

    ExtraPrecision::from_digits(digits, len)
}