00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <int N>
00021 TInteger<N>::TInteger (int i)
00022 {
00023 if (i >= 0)
00024 {
00025 memset(m_asBuffer,0,TINT_BYTES);
00026 }
00027 else
00028 {
00029 memset(m_asBuffer,0xFF,TINT_BYTES);
00030 }
00031 System::Memcpy(m_asBuffer,sizeof(int),&i,sizeof(int));
00032 #ifdef WM4_BIG_ENDIAN
00033 short sSave = m_asBuffer[0];
00034 m_asBuffer[0] = m_asBuffer[1];
00035 m_asBuffer[1] = sSave;
00036 #endif
00037 }
00038
00039 template <int N>
00040 TInteger<N>::TInteger (const TInteger& rkI)
00041 {
00042 System::Memcpy(m_asBuffer,TINT_BYTES,rkI.m_asBuffer,TINT_BYTES);
00043 }
00044
00045 template <int N>
00046 TInteger<N>::~TInteger ()
00047 {
00048 }
00049
00050 template <int N>
00051 TInteger<N>& TInteger<N>::operator= (const TInteger& rkI)
00052 {
00053 System::Memcpy(m_asBuffer,TINT_BYTES,rkI.m_asBuffer,TINT_BYTES);
00054 return *this;
00055 }
00056
00057 template <int N>
00058 int TInteger<N>::GetSign () const
00059 {
00060 return (m_asBuffer[TINT_LAST] & 0x8000) ? -1 : +1;
00061 }
00062
00063 template <int N>
00064 bool TInteger<N>::operator== (const TInteger& rkI) const
00065 {
00066 return Compare(*this,rkI) == 0;
00067 }
00068
00069 template <int N>
00070 bool TInteger<N>::operator!= (const TInteger& rkI) const
00071 {
00072 return Compare(*this,rkI) != 0;
00073 }
00074
00075 template <int N>
00076 bool TInteger<N>::operator< (const TInteger& rkI) const
00077 {
00078 int iS0 = GetSign(), iS1 = rkI.GetSign();
00079 if (iS0 > 0)
00080 {
00081 if (iS1 > 0)
00082 {
00083 return Compare(*this,rkI) < 0;
00084 }
00085 else
00086 {
00087 return false;
00088 }
00089 }
00090 else
00091 {
00092 if (iS1 > 0)
00093 {
00094 return true;
00095 }
00096 else
00097 {
00098 return Compare(*this,rkI) < 0;
00099 }
00100 }
00101 }
00102
00103 template <int N>
00104 bool TInteger<N>::operator<= (const TInteger& rkI) const
00105 {
00106 int iS0 = GetSign(), iS1 = rkI.GetSign();
00107 if (iS0 > 0)
00108 {
00109 if (iS1 > 0)
00110 {
00111 return Compare(*this,rkI) <= 0;
00112 }
00113 else
00114 {
00115 return false;
00116 }
00117 }
00118 else
00119 {
00120 if (iS1 > 0)
00121 {
00122 return true;
00123 }
00124 else
00125 {
00126 return Compare(*this,rkI) <= 0;
00127 }
00128 }
00129 }
00130
00131 template <int N>
00132 bool TInteger<N>::operator> (const TInteger& rkI) const
00133 {
00134 int iS0 = GetSign(), iS1 = rkI.GetSign();
00135 if (iS0 > 0)
00136 {
00137 if (iS1 > 0)
00138 {
00139 return Compare(*this,rkI) > 0;
00140 }
00141 else
00142 {
00143 return true;
00144 }
00145 }
00146 else
00147 {
00148 if (iS1 > 0)
00149 {
00150 return false;
00151 }
00152 else
00153 {
00154 return Compare(*this,rkI) > 0;
00155 }
00156 }
00157 }
00158
00159 template <int N>
00160 bool TInteger<N>::operator>= (const TInteger& rkI) const
00161 {
00162 int iS0 = GetSign(), iS1 = rkI.GetSign();
00163 if (iS0 > 0)
00164 {
00165 if (iS1 > 0)
00166 {
00167 return Compare(*this,rkI) >= 0;
00168 }
00169 else
00170 {
00171 return true;
00172 }
00173 }
00174 else
00175 {
00176 if (iS1 > 0)
00177 {
00178 return false;
00179 }
00180 else
00181 {
00182 return Compare(*this,rkI) >= 0;
00183 }
00184 }
00185 }
00186
00187 template <int N>
00188 int TInteger<N>::Compare (const TInteger<N>& rkI0, const TInteger<N>& rkI1)
00189 {
00190 for (int i = TINT_LAST; i >= 0; i--)
00191 {
00192 unsigned int uiValue0 = (unsigned int)rkI0.m_asBuffer[i];
00193 unsigned int uiValue1 = (unsigned int)rkI1.m_asBuffer[i];
00194 if (uiValue0 < uiValue1)
00195 {
00196 return -1;
00197 }
00198 else if (uiValue0 > uiValue1)
00199 {
00200 return +1;
00201 }
00202 }
00203 return 0;
00204 }
00205
00206 template <int N>
00207 TInteger<N> TInteger<N>::operator- () const
00208 {
00209 TInteger kResult = *this;
00210
00211
00212 int i;
00213 for (i = 0; i < TINT_SIZE; i++)
00214 {
00215 kResult.m_asBuffer[i] = ~kResult.m_asBuffer[i];
00216 }
00217
00218
00219 unsigned int uiCarry = 1;
00220 for (i = 0; i < TINT_SIZE; i++)
00221 {
00222 unsigned int uiB1 = kResult.ToUnsignedInt(i);
00223 unsigned int uiSum = uiB1 + uiCarry;
00224 kResult.FromUnsignedInt(i,uiSum);
00225 uiCarry = (uiSum & 0x00010000) ? 1 : 0;
00226 }
00227
00228
00229 if (kResult.GetSign() == GetSign())
00230 {
00231 assert(kResult == 0);
00232 }
00233
00234 return kResult;
00235 }
00236
00237 template <int N>
00238 TInteger<N> TInteger<N>::operator+ (const TInteger& rkI) const
00239 {
00240 TInteger kResult;
00241
00242 unsigned int uiCarry = 0;
00243 for (int i = 0; i < TINT_SIZE; i++)
00244 {
00245 unsigned int uiB0 = ToUnsignedInt(i);
00246 unsigned int uiB1 = rkI.ToUnsignedInt(i);
00247 unsigned int uiSum = uiB0 + uiB1 + uiCarry;
00248 kResult.FromUnsignedInt(i,uiSum);
00249 uiCarry = (uiSum & 0x00010000) ? 1 : 0;
00250 }
00251
00252
00253 if (GetSign() == rkI.GetSign())
00254 {
00255 assert(kResult.GetSign() == GetSign());
00256 }
00257
00258 return kResult;
00259 }
00260
00261 template <int N>
00262 TInteger<N> TInteger<N>::operator- (const TInteger& rkI) const
00263 {
00264 return *this + (-rkI);
00265 }
00266
00267 template <int N>
00268 TInteger<N> TInteger<N>::operator* (const TInteger& rkI) const
00269 {
00270 int iS0 = GetSign(), iS1 = rkI.GetSign(), iSProduct = iS0*iS1;
00271 TInteger kOp0 = (iS0 > 0 ? *this : -*this);
00272 TInteger kOp1 = (iS1 > 0 ? rkI : -rkI);
00273
00274
00275 unsigned short ausProduct[2*TINT_SIZE];
00276 unsigned short* pusPCurrent = ausProduct;
00277
00278
00279 unsigned short ausResult[2*TINT_SIZE];
00280 unsigned short* pusRCurrent = ausResult;
00281 memset(ausResult,0,2*TINT_BYTES);
00282
00283 for (int i0 = 0, iSize = 2*TINT_SIZE; i0 < TINT_SIZE; i0++, iSize--)
00284 {
00285 unsigned int uiB0 = kOp0.ToUnsignedInt(i0);
00286 if (uiB0 > 0)
00287 {
00288 unsigned short* pusPBuffer = pusPCurrent;
00289 unsigned int uiCarry = 0;
00290 int i1;
00291 for (i1 = 0; i1 < TINT_SIZE; i1++)
00292 {
00293 unsigned int uiB1 = kOp1.ToUnsignedInt(i1);
00294 unsigned int uiProd = uiB0*uiB1 + uiCarry;
00295 *pusPBuffer++ = (unsigned short)(uiProd & 0x0000FFFF);
00296 uiCarry = (uiProd & 0xFFFF0000) >> 16;
00297 }
00298 *pusPBuffer = (unsigned short)uiCarry;
00299
00300 unsigned short* pusRBuffer = pusRCurrent;
00301 pusPBuffer = pusPCurrent;
00302 uiCarry = 0;
00303 unsigned int uiSum, uiTerm0, uiTerm1;
00304 for (i1 = 0; i1 <= TINT_SIZE; i1++)
00305 {
00306 uiTerm0 = (unsigned int)(*pusPBuffer++);
00307 uiTerm1 = (unsigned int)(*pusRBuffer);
00308 uiSum = uiTerm0 + uiTerm1 + uiCarry;
00309 *pusRBuffer++ = (unsigned short)(uiSum & 0x0000FFFF);
00310 uiCarry = (uiSum & 0x00010000) ? 1 : 0;
00311 }
00312
00313 for (; uiCarry > 0 && i1 < iSize; i1++)
00314 {
00315 uiTerm0 = (unsigned int)(*pusRBuffer);
00316 uiSum = uiTerm0 + uiCarry;
00317 *pusRBuffer++ = (unsigned short)(uiSum & 0x0000FFFF);
00318 uiCarry = (uiSum & 0x00010000) ? 1 : 0;
00319 }
00320 }
00321
00322 pusPCurrent++;
00323 pusRCurrent++;
00324 }
00325
00326
00327
00328
00329
00330 for (int i = 2*TINT_SIZE-1; i >= TINT_SIZE; i--)
00331 {
00332 assert(ausResult[i] == 0);
00333 }
00334 assert((ausResult[TINT_LAST] & 0x8000) == 0);
00335
00336 TInteger kResult;
00337 System::Memcpy(kResult.m_asBuffer,TINT_BYTES,ausResult,TINT_BYTES);
00338 if (iSProduct < 0)
00339 {
00340 kResult = -kResult;
00341 }
00342
00343 return kResult;
00344 }
00345
00346 template <int N>
00347 TInteger<N> operator* (int i, const TInteger<N>& rkI)
00348 {
00349 return rkI*i;
00350 }
00351
00352 template <int N>
00353 TInteger<N> TInteger<N>::operator/ (const TInteger& rkI) const
00354 {
00355
00356 TInteger kQ, kR;
00357 return (GetDivMod(*this,rkI,kQ,kR) ? kQ : 0);
00358 }
00359
00360 template <int N>
00361 TInteger<N> TInteger<N>::operator% (const TInteger& rkI) const
00362 {
00363
00364 TInteger kQ, kR;
00365 return (GetDivMod(*this,rkI,kQ,kR) ? kR : 0);
00366 }
00367
00368 template <int N>
00369 TInteger<N>& TInteger<N>::operator+= (const TInteger& rkI)
00370 {
00371 *this = *this + rkI;
00372 return *this;
00373 }
00374
00375 template <int N>
00376 TInteger<N>& TInteger<N>::operator-= (const TInteger& rkI)
00377 {
00378 *this = *this - rkI;
00379 return *this;
00380 }
00381
00382 template <int N>
00383 TInteger<N>& TInteger<N>::operator*= (const TInteger& rkI)
00384 {
00385 *this = *this * rkI;
00386 return *this;
00387 }
00388
00389 template <int N>
00390 TInteger<N>& TInteger<N>::operator/= (const TInteger& rkI)
00391 {
00392 *this = *this / rkI;
00393 return *this;
00394 }
00395
00396 template <int N>
00397 TInteger<N> TInteger<N>::operator<< (int iShift) const
00398 {
00399 if (iShift < 0)
00400 {
00401 return 0;
00402 }
00403 if (iShift == 0)
00404 {
00405 return *this;
00406 }
00407
00408
00409 TInteger kResult;
00410 int iBlocks = iShift / 16;
00411 if (iBlocks > TINT_LAST)
00412 {
00413 return 0;
00414 }
00415
00416 int i;
00417 if (iBlocks > 0)
00418 {
00419 int j = TINT_LAST-iBlocks;
00420 for (i = TINT_LAST; j >= 0; i--, j--)
00421 {
00422 kResult.m_asBuffer[i] = m_asBuffer[j];
00423 }
00424
00425 for (; i >= 0; i--)
00426 {
00427 kResult.m_asBuffer[i] = 0;
00428 }
00429 }
00430
00431
00432 int iBits = iShift % 16;
00433 if (iBits > 0)
00434 {
00435 unsigned int uiLo, uiHi, uiValue;
00436 int iM1;
00437 for (i = TINT_LAST, iM1 = i-1; iM1 >= 0; i--, iM1--)
00438 {
00439 uiLo = ToUnsignedInt(iM1);
00440 uiHi = ToUnsignedInt(i);
00441 uiValue = (uiLo | (uiHi << 16));
00442 uiValue <<= iBits;
00443 kResult.FromUnsignedInt(i,((0xFFFF0000 & uiValue) >> 16));
00444 }
00445
00446 uiValue = ToUnsignedInt(0);
00447 uiValue <<= iBits;
00448 kResult.FromUnsignedInt(0,(0x0000FFFF & uiValue));
00449 }
00450
00451 return kResult;
00452 }
00453
00454 template <int N>
00455 TInteger<N> TInteger<N>::operator>> (int iShift) const
00456 {
00457 if (iShift < 0)
00458 {
00459 return 0;
00460 }
00461 if (iShift == 0)
00462 {
00463 return *this;
00464 }
00465
00466
00467 TInteger kResult;
00468 int iBlocks = iShift/16;
00469 if (iBlocks > TINT_LAST)
00470 {
00471 return 0;
00472 }
00473
00474 int i;
00475 if (iBlocks > 0)
00476 {
00477 int j = iBlocks;
00478 for (i = 0; j <= TINT_LAST; i++, j++)
00479 {
00480 kResult.m_asBuffer[i] = m_asBuffer[j];
00481 }
00482
00483 if (GetSign() > 0)
00484 {
00485 for (; i <= TINT_LAST; i++)
00486 {
00487 kResult.m_asBuffer[i] = 0;
00488 }
00489 }
00490 else
00491 {
00492 for (; i <= TINT_LAST; i++)
00493 {
00494 kResult.m_asBuffer[i] = (short)(0x0000FFFF);
00495 }
00496 }
00497 }
00498
00499
00500 int iBits = iShift % 16;
00501 if (iBits > 0)
00502 {
00503 unsigned int uiValue;
00504 int iP1;
00505 for (i = 0, iP1 = 1; iP1 <= TINT_LAST; i++, iP1++)
00506 {
00507 uiValue = ToUnsignedInt(i,iP1);
00508 uiValue >>= iBits;
00509 kResult.FromUnsignedInt(i,uiValue);
00510 }
00511
00512 uiValue = ToUnsignedInt(TINT_LAST);
00513 if (GetSign() < 0)
00514 {
00515 uiValue |= 0xFFFF0000;
00516 }
00517 uiValue >>= iBits;
00518 kResult.FromUnsignedInt(TINT_LAST,uiValue);
00519 }
00520
00521 return kResult;
00522 }
00523
00524 template <int N>
00525 TInteger<N>& TInteger<N>::operator<<= (int iShift)
00526 {
00527 if (iShift <= 0)
00528 {
00529 return *this;
00530 }
00531
00532
00533 TInteger kResult;
00534 int iBlocks = iShift/16;
00535 if (iBlocks > TINT_LAST)
00536 {
00537 return *this;
00538 }
00539
00540 int i;
00541 if (iBlocks > 0)
00542 {
00543 int j = TINT_LAST-iBlocks;
00544 for (i = TINT_LAST; j >= 0; i--, j--)
00545 {
00546 m_asBuffer[i] = m_asBuffer[j];
00547 }
00548
00549 for (; i >= 0; i--)
00550 {
00551 m_asBuffer[i] = 0;
00552 }
00553 }
00554
00555
00556 int iBits = iShift % 16;
00557 if (iBits > 0)
00558 {
00559 unsigned int uiValue;
00560 int iM1;
00561 for (i = TINT_LAST, iM1 = i-1; iM1 >= 0; i--, iM1--)
00562 {
00563 uiValue = ToUnsignedInt(iM1,i);
00564 uiValue <<= iBits;
00565 FromUnsignedInt(i,((0xFFFF0000 & uiValue) >> 16));
00566 }
00567
00568 uiValue = ToUnsignedInt(0);
00569 uiValue <<= iBits;
00570 FromUnsignedInt(0,(0x0000FFFF & uiValue));
00571 }
00572
00573 return *this;
00574 }
00575
00576 template <int N>
00577 TInteger<N>& TInteger<N>::operator>>= (int iShift)
00578 {
00579 if (iShift <= 0)
00580 {
00581 return *this;
00582 }
00583
00584
00585 int iBlocks = iShift/16;
00586 if (iBlocks > TINT_LAST)
00587 {
00588 return *this;
00589 }
00590
00591 int i;
00592 if (iBlocks > 0)
00593 {
00594 int j = iBlocks;
00595 for (i = 0, j = iBlocks; j <= TINT_LAST; i++, j++)
00596 {
00597 m_asBuffer[i] = m_asBuffer[j];
00598 }
00599
00600 if (GetSign() > 0)
00601 {
00602 for (; i <= TINT_LAST; i++)
00603 {
00604 m_asBuffer[i] = 0;
00605 }
00606 }
00607 else
00608 {
00609 for (; i <= TINT_LAST; i++)
00610 {
00611 m_asBuffer[i] = (short)(0x0000FFFF);
00612 }
00613 }
00614 }
00615
00616
00617 int iBits = iShift % 16;
00618 if (iBits > 0)
00619 {
00620 unsigned int uiValue;
00621 int iP1;
00622 for (i = 0, iP1 = 1; iP1 <= TINT_LAST; i++, iP1++)
00623 {
00624 uiValue = ToUnsignedInt(i,iP1);
00625 uiValue >>= iBits;
00626 FromUnsignedInt(i,uiValue);
00627 }
00628
00629 uiValue = ToUnsignedInt(TINT_LAST);
00630 if (GetSign() < 0)
00631 {
00632 uiValue |= 0xFFFF0000;
00633 }
00634 uiValue >>= iBits;
00635 FromUnsignedInt(TINT_LAST,uiValue);
00636 }
00637
00638 return *this;
00639 }
00640
00641 template <int N>
00642 bool TInteger<N>::GetDivMod (const TInteger& rkNumer, const TInteger& rkDenom,
00643 TInteger& rkQuo, TInteger& rkRem)
00644 {
00645 if (rkDenom == 0)
00646 {
00647 assert(false);
00648 rkQuo = 0;
00649 rkRem = 0;
00650 return false;
00651 }
00652
00653 if (rkNumer == 0)
00654 {
00655 rkQuo = 0;
00656 rkRem = 0;
00657 return true;
00658 }
00659
00660
00661 int iS0 = rkNumer.GetSign(), iS1 = rkDenom.GetSign();
00662 TInteger kAbsNumer = iS0*rkNumer;
00663 TInteger kAbsDenom = iS1*rkDenom;
00664
00665 int iCompare = Compare(kAbsNumer,kAbsDenom);
00666 if (iCompare < 0)
00667 {
00668
00669 rkQuo = 0;
00670 rkRem = rkNumer;
00671 return true;
00672 }
00673
00674 if (iCompare == 0)
00675 {
00676
00677 rkQuo = 1;
00678 rkRem = 0;
00679 return true;
00680 }
00681
00682
00683 if (kAbsDenom > 0x0000FFFF)
00684 {
00685 DivMultiple(kAbsNumer,kAbsDenom,rkQuo,rkRem);
00686 }
00687 else
00688 {
00689 DivSingle(kAbsNumer,kAbsDenom.m_asBuffer[0],rkQuo,rkRem);
00690 }
00691
00692
00693 rkQuo *= iS0*iS1;
00694 rkRem *= iS0;
00695
00696 #ifdef _DEBUG
00697 TInteger kTest = rkNumer - rkDenom*rkQuo - rkRem;
00698 assert(kTest == 0);
00699 #endif
00700 return true;
00701 }
00702
00703 template <int N>
00704 void TInteger<N>::DivSingle (const TInteger& rkNumer, short sDenom,
00705 TInteger& rkQuo, TInteger& rkRem)
00706 {
00707
00708 unsigned int uiDenom = 0x0000FFFF & (unsigned int)sDenom;
00709
00710
00711 int iNStart = rkNumer.GetLeadingBlock();
00712 const short* psNumer = &rkNumer.m_asBuffer[iNStart];
00713 unsigned int uiDigit1 = 0;
00714
00715
00716 short* psQuo = &rkQuo.m_asBuffer[iNStart];
00717 rkQuo = 0;
00718 int iLastNonZero = -1;
00719 for (int i = iNStart; i >= 0; i--, psNumer--, psQuo--)
00720 {
00721 unsigned int uiDigitB = uiDigit1;
00722 uiDigit1 = 0x0000FFFF & (unsigned int)(*psNumer);
00723 unsigned int uiNumer = (uiDigitB << 16) | uiDigit1;
00724 unsigned int uiQuo = uiNumer/uiDenom;
00725 uiDigit1 = uiNumer - uiQuo*uiDenom;
00726 *psQuo = (short)(uiQuo & 0x0000FFFF);
00727 if (iLastNonZero == -1 && uiQuo > 0)
00728 {
00729 iLastNonZero = i;
00730 }
00731 }
00732 assert(iLastNonZero >= 0);
00733
00734
00735 size_t uiSize;
00736 rkRem = 0;
00737 if (uiDigit1 & 0xFFFF0000)
00738 {
00739 uiSize = 2*sizeof(short);
00740 System::Memcpy(rkRem.m_asBuffer,uiSize,&uiDigit1,uiSize);
00741 #ifdef WM4_BIG_ENDIAN
00742 short sSave = rkRem.m_asBuffer[0];
00743 rkRem.m_asBuffer[0] = rkRem.m_asBuffer[1];
00744 rkRem.m_asBuffer[1] = sSave;
00745 #endif
00746 }
00747 else
00748 {
00749 unsigned short usDigit1 = (unsigned short)uiDigit1;
00750 uiSize = sizeof(short);
00751 System::Memcpy(rkRem.m_asBuffer,uiSize,&usDigit1,uiSize);
00752 }
00753 }
00754
00755 template <int N>
00756 void TInteger<N>::DivMultiple (const TInteger& rkNumer,
00757 const TInteger& rkDenom, TInteger& rkQuo, TInteger& rkRem)
00758 {
00759 rkQuo = 0;
00760 rkRem = 0;
00761
00762
00763
00764
00765
00766
00767
00768
00769 int iDInit = rkDenom.GetLeadingBlock();
00770 int iLeadingDigit = rkDenom.ToInt(iDInit);
00771 int iAdjust = 0x10000/(iLeadingDigit+1);
00772 TInteger kANum = iAdjust*rkNumer;
00773 TInteger kADen = iAdjust*rkDenom;
00774 assert(kADen.GetLeadingBlock() == iDInit);
00775
00776
00777 unsigned int uiD1 = kADen.ToUnsignedInt(iDInit);
00778 unsigned int uiD2 = kADen.ToUnsignedInt(iDInit-1);
00779
00780
00781 int iNInit = kANum.GetLeadingBlock();
00782 assert(iNInit >= iDInit);
00783 int iQInit;
00784 unsigned int uiRHat;
00785 if (iNInit != iDInit)
00786 {
00787 iQInit = iNInit-iDInit-1;
00788 uiRHat = 1;
00789 }
00790 else
00791 {
00792 iQInit = 0;
00793 uiRHat = 0;
00794 }
00795
00796 for (; iQInit >= 0; iQInit--)
00797 {
00798
00799 unsigned int uiN0, uiN1, uiN2;
00800 if (uiRHat > 0)
00801 {
00802 uiN0 = kANum.ToUnsignedInt(iNInit--);
00803 uiN1 = kANum.ToUnsignedInt(iNInit--);
00804 uiN2 = kANum.ToUnsignedInt(iNInit);
00805 }
00806 else
00807 {
00808 uiN0 = 0;
00809 uiN1 = kANum.ToUnsignedInt(iNInit--);
00810 uiN2 = kANum.ToUnsignedInt(iNInit);
00811 }
00812
00813
00814 unsigned int uiTmp = (uiN0 << 16) | uiN1;
00815 unsigned int uiQHat = (uiN0 != uiD1 ? uiTmp/uiD1 : 0x0000FFFF);
00816 unsigned int uiProd = uiQHat*uiD1;
00817 assert(uiTmp >= uiProd);
00818 uiRHat = uiTmp - uiProd;
00819 if (uiD2*uiQHat > 0x10000*uiRHat + uiN2)
00820 {
00821 uiQHat--;
00822 uiRHat += uiD1;
00823 if (uiD2*uiQHat > 0x10000*uiRHat + uiN2)
00824 {
00825
00826
00827
00828 uiQHat--;
00829 uiRHat += uiD1;
00830 }
00831 }
00832
00833
00834 TInteger kLocalQuo;
00835 kLocalQuo.FromUnsignedInt(iQInit,uiQHat);
00836
00837
00838 TInteger kProduct = kLocalQuo*kADen;
00839 kANum -= kProduct;
00840 if (kANum < 0)
00841 {
00842 uiQHat--;
00843 kANum += kADen;
00844 assert(kANum >= 0);
00845 }
00846
00847
00848 rkQuo.FromUnsignedInt(iQInit,uiQHat);
00849
00850 if (kANum >= kADen)
00851 {
00852
00853 iNInit = kANum.GetLeadingBlock();
00854 }
00855 else
00856 {
00857
00858 break;
00859 }
00860 }
00861
00862
00863 if (kANum > 0)
00864 {
00865 short sDivisor = (short)(iAdjust & 0x0000FFFF);
00866 TInteger kShouldBeZero;
00867 DivSingle(kANum,sDivisor,rkRem,kShouldBeZero);
00868 }
00869 else
00870 {
00871 rkRem = 0;
00872 }
00873 }
00874
00875 template <int N>
00876 int TInteger<N>::GetLeadingBlock () const
00877 {
00878 for (int i = TINT_LAST; i >= 0; i--)
00879 {
00880 if (m_asBuffer[i] != 0)
00881 {
00882 return i;
00883 }
00884 }
00885 return -1;
00886 }
00887
00888 template <int N>
00889 int TInteger<N>::GetTrailingBlock () const
00890 {
00891 for (int i = 0; i <= TINT_LAST; i++)
00892 {
00893 if (m_asBuffer[i] != 0)
00894 {
00895 return i;
00896 }
00897 }
00898 return -1;
00899 }
00900
00901 template <int N>
00902 int TInteger<N>::GetLeadingBit (int i) const
00903 {
00904 assert(0 <= i && i <= TINT_LAST);
00905 if (i < 0 || i > TINT_LAST)
00906 {
00907 return -1;
00908 }
00909
00910
00911
00912 int iValue = (int)m_asBuffer[i];
00913 if ((iValue & 0xFF00) != 0)
00914 {
00915 if ((iValue & 0xF000) != 0)
00916 {
00917 if ((iValue & 0xC000) != 0)
00918 {
00919 if ((iValue & 0x8000) != 0)
00920 {
00921 return 15;
00922 }
00923 else
00924 {
00925 return 14;
00926 }
00927 }
00928 else
00929 {
00930 if ((iValue & 0x2000) != 0)
00931 {
00932 return 13;
00933 }
00934 else
00935 {
00936 return 12;
00937 }
00938 }
00939 }
00940 else
00941 {
00942 if ((iValue & 0x0C00) != 0)
00943 {
00944 if ((iValue & 0x0800) != 0)
00945 {
00946 return 11;
00947 }
00948 else
00949 {
00950 return 10;
00951 }
00952 }
00953 else
00954 {
00955 if ((iValue & 0x0200) != 0)
00956 {
00957 return 9;
00958 }
00959 else
00960 {
00961 return 8;
00962 }
00963 }
00964 }
00965 }
00966 else
00967 {
00968 if ((iValue & 0x00F0) != 0)
00969 {
00970 if ((iValue & 0x00C0) != 0)
00971 {
00972 if ((iValue & 0x0080) != 0)
00973 {
00974 return 7;
00975 }
00976 else
00977 {
00978 return 6;
00979 }
00980 }
00981 else
00982 {
00983 if ((iValue & 0x0020) != 0)
00984 {
00985 return 5;
00986 }
00987 else
00988 {
00989 return 4;
00990 }
00991 }
00992 }
00993 else
00994 {
00995 if ((iValue & 0x000C) != 0)
00996 {
00997 if ((iValue & 0x0008) != 0)
00998 {
00999 return 3;
01000 }
01001 else
01002 {
01003 return 2;
01004 }
01005 }
01006 else
01007 {
01008 if ((iValue & 0x0002) != 0)
01009 {
01010 return 1;
01011 }
01012 else
01013 {
01014 return 0;
01015 }
01016 }
01017 }
01018 }
01019
01020 return -1;
01021 }
01022
01023 template <int N>
01024 int TInteger<N>::GetTrailingBit (int i) const
01025 {
01026 assert(0 <= i && i <= TINT_LAST);
01027 if (i < 0 || i > TINT_LAST)
01028 {
01029 return -1;
01030 }
01031
01032
01033
01034 int iValue = (int)m_asBuffer[i];
01035 if ((iValue & 0x00FF) != 0)
01036 {
01037 if ((iValue & 0x000F) != 0)
01038 {
01039 if ((iValue & 0x0003) != 0)
01040 {
01041 if ((iValue & 0x0001) != 0)
01042 {
01043 return 0;
01044 }
01045 else
01046 {
01047 return 1;
01048 }
01049 }
01050 else
01051 {
01052 if ((iValue & 0x0004) != 0)
01053 {
01054 return 2;
01055 }
01056 else
01057 {
01058 return 3;
01059 }
01060 }
01061 }
01062 else
01063 {
01064 if ((iValue & 0x0030) != 0)
01065 {
01066 if ((iValue & 0x0010) != 0)
01067 {
01068 return 4;
01069 }
01070 else
01071 {
01072 return 5;
01073 }
01074 }
01075 else
01076 {
01077 if ((iValue & 0x0040) != 0)
01078 {
01079 return 6;
01080 }
01081 else
01082 {
01083 return 7;
01084 }
01085 }
01086 }
01087 }
01088 else
01089 {
01090 if ((iValue & 0x0F00) != 0)
01091 {
01092 if ((iValue & 0x0300) != 0)
01093 {
01094 if ((iValue & 0x0100) != 0)
01095 {
01096 return 8;
01097 }
01098 else
01099 {
01100 return 9;
01101 }
01102 }
01103 else
01104 {
01105 if ((iValue & 0x0400) != 0)
01106 {
01107 return 10;
01108 }
01109 else
01110 {
01111 return 11;
01112 }
01113 }
01114 }
01115 else
01116 {
01117 if ((iValue & 0x3000) != 0)
01118 {
01119 if ((iValue & 0x1000) != 0)
01120 {
01121 return 12;
01122 }
01123 else
01124 {
01125 return 13;
01126 }
01127 }
01128 else
01129 {
01130 if ((iValue & 0x4000) != 0)
01131 {
01132 return 14;
01133 }
01134 else
01135 {
01136 return 15;
01137 }
01138 }
01139 }
01140 }
01141
01142 return -1;
01143 }
01144
01145 template <int N>
01146 int TInteger<N>::GetLeadingBit () const
01147 {
01148 int iBlock = GetLeadingBlock();
01149 if (iBlock >= 0)
01150 {
01151 int iBit = GetLeadingBit(iBlock);
01152 if (iBit >= 0)
01153 {
01154 return iBit+16*iBlock;
01155 }
01156 }
01157
01158 return -1;
01159 }
01160
01161 template <int N>
01162 int TInteger<N>::GetTrailingBit () const
01163 {
01164 int iBlock = GetTrailingBlock();
01165 if (iBlock >= 0)
01166 {
01167 int iBit = GetTrailingBit(iBlock);
01168 if (iBit >= 0)
01169 {
01170 return iBit+16*iBlock;
01171 }
01172 }
01173
01174 return -1;
01175 }
01176
01177 template <int N>
01178 void TInteger<N>::SetBit (int i, bool bOn)
01179 {
01180
01181 int iBlock = i/16;
01182 int iBit = i%16;
01183 if (bOn)
01184 {
01185 m_asBuffer[iBlock] |= (1 << iBit);
01186 }
01187 else
01188 {
01189 m_asBuffer[iBlock] &= ~(1 << iBit);
01190 }
01191 }
01192
01193 template <int N>
01194 bool TInteger<N>::GetBit (int i) const
01195 {
01196
01197 int iBlock = i/16;
01198 int iBit = i%16;
01199 return (m_asBuffer[iBlock] & (1 << iBit)) != 0;
01200 }
01201
01202 template <int N>
01203 unsigned int TInteger<N>::ToUnsignedInt (int i) const
01204 {
01205
01206 return 0x0000FFFF & (unsigned int)m_asBuffer[i];
01207 }
01208
01209 template <int N>
01210 void TInteger<N>::FromUnsignedInt (int i, unsigned int uiValue)
01211 {
01212
01213 m_asBuffer[i] = (short)(uiValue & 0x0000FFFF);
01214 }
01215
01216 template <int N>
01217 unsigned int TInteger<N>::ToUnsignedInt (int iLo, int iHi) const
01218 {
01219 unsigned int uiLo = ToUnsignedInt(iLo);
01220 unsigned int uiHi = ToUnsignedInt(iHi);
01221 return (uiLo | (uiHi << 16));
01222 }
01223
01224 template <int N>
01225 int TInteger<N>::ToInt (int i) const
01226 {
01227
01228 return (int)(0x0000FFFF & (unsigned int)m_asBuffer[i]);
01229 }
01230
01231 }