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
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
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;
}