示例#1
0
EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const
	{
	RInteger product = PositiveMultiplyL(*this, aOperand);

	if (NotNegative() != aOperand.NotNegative())
		{
		product.Negate();
		}
	return product;
	}
示例#2
0
EXPORT_C TInteger& TInteger::operator++()
	{
	if(NotNegative())
		{
		if(Increment(Ptr(), Size()))
			{
			CleanGrowL(2*Size());
			(Ptr())[Size()/2]=1;
			}
		}
	else
		{
		DecrementNoCarry(Ptr(), Size());
		if(WordCount()==0)
			{
			this->CopyL(Zero());
			}
		}
	return *this;
	}
示例#3
0
EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const
	{
	RInteger diff;
    if (NotNegative())
		{
        if (aOperand.NotNegative())
            diff = PositiveSubtractL(*this, aOperand);
        else
            diff = PositiveAddL(*this, aOperand);
		}
    else
		{
        if (aOperand.NotNegative())
			{
            diff = PositiveAddL(*this, aOperand);
			diff.SetSign(TInteger::ENegative);
			}
        else
            diff = PositiveSubtractL(aOperand, *this);
		}
	return diff;
	}
示例#4
0
EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const
	{
	RInteger sum;
    if (NotNegative())
		{
        if (aOperand.NotNegative())
            sum = PositiveAddL(*this, aOperand);
        else
            sum = PositiveSubtractL(*this, aOperand);
		}
    else
		{
        if (aOperand.NotNegative())
            sum = PositiveSubtractL(aOperand, *this);
        else
			{
            sum = PositiveAddL(*this, aOperand);
			sum.SetSign(TInteger::ENegative);
			}
		}
	return sum;
	}
示例#5
0
 bool IsPositive()  const { return NotNegative() && NotZero(); }
示例#6
0
void TInteger::PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr)
	{
	assert(aBits > 1); 
	
	//"this" is "empty" currently.  Consists of Size() words of 0's.  This is just
	//checking that sign flag is positive as we don't set it later.
	assert(NotNegative());

	//Flag for the whole function saying if we've found a prime
	TBool foundProbablePrime = EFalse;

	//Find 2^aBits + 1 -- any prime we find must be less than this.
	RInteger max = RInteger::NewEmptyL(BitsToWords(aBits)+1);
	CleanupStack::PushL(max);
	max.SetBit(aBits);
	assert(max.BitCount()-1 == aBits);

	// aBits 	| approx number of odd numbers you must try to have a 50% 
	//			chance of finding a prime
	//---------------------------------------------------------
	// 512		| 122		
	// 1024		| 245
	// 2048		| 1023
	//Therefore if we are generating larger than 1024 bit numbers we'll use a
	//bigger bit array to have a better chance of avoiding re-generating it.
	TUint sLength = aBits > 1024 ? 1024 : 512;
	RInteger S = RInteger::NewEmptyL(BitsToWords(sLength));
	CleanupStack::PushL(S);

	while(!foundProbablePrime)
		{
		//Randomly choose aBits
		RandomizeL(aBits, aAttr);

		//If the random number chosen is less than KSmallPrimeSquared, we have a
		//special set of routines.
		if(SmallPrimeRandomizeL())
			{
			foundProbablePrime = ETrue;
			}
		else
			{
			//if it was <= KLastSmallPrimeSquared then it would have been
			//handled by SmallPrimeRandomizeL()
			assert(*this > KLastSmallPrimeSquared);

			//Make sure any number we bother testing is at least odd
			SetBit(0);

			//Ensure that this + 2*sLength < max
			RInteger temp = max.MinusL(*this);
			CleanupStack::PushL(temp);
			++temp;
			temp >>=1;
			if(temp < sLength)
				{
				//if this + 2*sLength >= max then we use a smaller sLength to
				//ensure we don't find a number that is outside of our bounds
				//(and bigger than our allocated memory for this)

				//temp must be less than KMaxTUint as sLength is a TUint 
				sLength = temp.ConvertToUnsignedLong();	
				}
			CleanupStack::PopAndDestroy(&temp);

			//Start at 1 as no point in checking against 2 (all odd numbers)
			for(TUint i=1; i<KPrimeTableSize; i++)
				{
				//no need to call ModuloL as we know KPrimeTable[i] is not 0
				TUint remainder = Modulo(*this, KPrimeTable[i]);
				TUint index = FindSmallestIndex(KPrimeTable[i], remainder);
				EliminateComposites(S.Ptr(), KPrimeTable[i], index, sLength);
				}
			TInt j = FindFirstPrimeCandidate(S.Ptr(), sLength);
			TInt prev = 0;
			for(; j>=0; j=FindFirstPrimeCandidate(S.Ptr(), sLength))
				{
				ArraySetBit(S.Ptr(), j);

				//should never carry as we earlier made sure that 2*j + this < max
				//where max is 1 bit more than we asked for.
				IncrementNoCarry(Ptr(), Size(), 2*(j-prev));

				assert(*this < max);
				assert(!HasSmallDivisorL(*this));

				prev = j;

				if( IsStrongProbablePrimeL(*this) )
					{
					foundProbablePrime = ETrue;
					break;
					}
				}
			//This clears the memory
			S.CopyL(0, EFalse);
			}
		}
	CleanupStack::PopAndDestroy(2, &max);
	}
示例#7
0
EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const
	{
	//Binary GCD algorithm -- see HAC 14.4.1
	//with a slight variation -- our g counts shifts rather than actually
	//shifting.  We then do one shift at the end.
	assert(NotNegative());
	assert(aOperand.NotNegative());

	RInteger x = RInteger::NewL(*this);
	CleanupStack::PushL(x);
	RInteger y = RInteger::NewL(aOperand);
	CleanupStack::PushL(y);

	// 1 Ensure x >= y
	if( x < y )
		{
		TClassSwap(x, y);
		}

	TUint g = 0;
	// 2 while x and y even x <- x/2, y <- y/2
	while( x.IsEven() && y.IsEven() )
		{
		x >>= 1;
		y >>= 1;
		++g;
		}
	// 3 while x != 0
	while( x.NotZero() )
		{
		// 3.1 while x even x <- x/2
		while( x.IsEven() )
			{
			x >>= 1;
			}
		// 3.2 while y even y <- y/2
		while( y.IsEven() )
			{
			y >>= 1;
			}
		// 3.3 t <- abs(x-y)/2
		RInteger t = x.MinusL(y);
		t >>= 1;
		t.SetSign(TInteger::EPositive);

		// 3.4 If x>=y then x <- t else y <- t
		if( x >= y )
			{
			x.Set(t);
			}
		else 
			{
			y.Set(t);
			}
		}
	
	// 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually
	//shifting)
	y <<= g;
	CleanupStack::Pop(&y);
	CleanupStack::PopAndDestroy(&x); 
	return y;
	}