Kivonás


Ez a függvény a-mult*b*256pow értéket számítja ki. mult egydigites. A visszatérési értéket egy dinamikusan lefoglalt területen adja vissza a függvény, amelyet a NewNumber fügvénnyel allokál. a és b értéke érintetlen marad.

Megjegyzés: Nincs ellenőrzés a két szám nagyságára, és az eredmény csak akkor értelmes, ha pozitív. A hívó programrésznek kell a függvény meghívása előtt ellenőrizni, hogy a>mult*b*256pow

A felhasznált típusok: u8 és u32 8 illetve 32 bites előjel nélküli egészek.

void powerSub(Number a, Number b, int pow, u8 mult){
 register int j,lim;
 register u32 cy0,cy1,mcy0,BB;
 register u8 *p,*q;
Bpow(j) nem más, mint b j-edik digitje. Ezt a makrót nyugodtan használhatjuk akkor is, ha j nagyobb, mint b legnagyobb értékes helyiértéke. A sebesség növelése érdekében a megfelelő digitet a q mutatón keresztül éri el a program, ezért nagyon kell vigyázni, hogy ez a mutató mindig a megfelelő helyre mutasson.
#define Bpow(j) ((u32)(j n+pow ? *q : 0))
#define min(x,y) ((x)<(y)?(x):(y)) 
A különböző átviteli változók értéke kezdetkor nulla, és a helyiérték limit a két szám legnagyobb helyiértékének kissebbike. p a sebesség növelése érdekében az a szám mindig aktuális bitjére mutat, míg q ugyanezt teszi b digitjeivel.
 cy0 = mcy0 = 0;
 lim = min(a->n , b->n+pow);
 p = a->digit+pow;
 j = pow;
 for( q = b->digit ; j n); j++ , p++ , q++ ){
BB felveszi azt az értéket, amit a aktuális digitjéből le kell vonni. Ez nem más, mint b megfelelő digitje megszorozva a szorzóparaméterrel, plusz azok az értékek, amelyek túlcsordulás miatt nem lehetett levonni a kisebb digitből.
 BB = Bpow(j)*mult+mcy0+cy0;
Ennek a számnak a 256-nál nagyobb részét biztos, hogy nem lehet levonni ebből a digitből. Ezt majd a következő ciklusban kell levonni a következő digitből, természetesen a helyiértéknek megfelelően csak a 256-od részét. A most levonandó érték pedig az, ami 8 biten elfér.
 mcy0 = BB >> 8;
 BB &= 0xff;
Ha az így keletkezett levonandó érték nem vonható le a aktuális digitjéből, akkor kölcsön kell venni az egyel nagyobb helyiértékű digitből egyet, ez cy1. Ugyanakkor ezt a következő ciklusban vissza kell majd adni, ez }cy0}.
 if( ((u32)*p) <((u32)bb) )cy1="POW2_8;" else cy1="0;" *p="(u8)(cy1+((u32)*p)-BB);" cy0="!(!cy1);" } 
Ha itt maradt kölcsönvett bit, akkor a hívó függvény nem ellenőrizte, hogy a kivonás elvégezhető.
 if( cy0 ){
 ReportLog('I',
"\nInternal Error\nin powerSub pow=%d, mult=%d\npowerCompare=%d",
 pow, mult,powerCompare(a,b,pow));
 }
Kiszámítjuk az eredmény hosszát.
 for( j = a->n ; j && !a->digit[--j] ; )
 continue;
 j++;
 a->n = j;
 return;
 }

toc