crypto/weakcryptospi/source/bigint/bigint.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Sat, 20 Feb 2010 00:36:18 +0200
branchRCL_3
changeset 43 9b5a3a9fddf8
parent 17 cd501b96611d
child 72 de46a57f75fb
permissions -rw-r--r--
Revision: 201007 Kit: 201007
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     1
/*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     2
* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     3
* All rights reserved.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     4
* This component and the accompanying materials are made available
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     6
* which accompanies this distribution, and is available
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     8
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     9
* Initial Contributors:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    11
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    12
* Contributors:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    13
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    14
* Description: 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    15
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    16
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    17
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    18
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    19
#include <random.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    20
#include <bigint.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    21
#include <e32std.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    22
#include <euserext.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    23
#include <securityerr.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    24
#include "words.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    25
#include "algorithms.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    26
#include "windowslider.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    27
#include "stackinteger.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    28
#include "mont.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    29
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    30
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    31
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    32
* Creates a new buffer containing the big-endian binary representation of this
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    33
* integer.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    34
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    35
* Note that it does not support the exporting of negative integers.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    36
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    37
* @return	The new buffer.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    38
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    39
* @leave KErrNegativeExportNotSupported	If this instance is a negative integer.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    40
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    41
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    42
EXPORT_C HBufC8* TInteger::BufferLC() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    43
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    44
	if(IsNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    45
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    46
		User::Leave(KErrNegativeExportNotSupported);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    47
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    48
	TUint bytes = ByteCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    49
	HBufC8* buf = HBufC8::NewMaxLC(bytes);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    50
	TUint8* bufPtr = (TUint8*)(buf->Ptr());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    51
	TUint8* regPtr = (TUint8*)Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    52
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    53
	// we internally store the number little endian, as a string we want it big
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    54
	// endian
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    55
	for(TUint i=0,j=bytes-1; i<bytes; )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    56
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    57
		bufPtr[i++] = regPtr[j--];
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    58
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    59
	return buf;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    60
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    61
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    62
EXPORT_C HBufC8* TInteger::BufferWithNoTruncationLC() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    63
 	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    64
 	if(IsNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    65
 		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    66
 		User::Leave(KErrNegativeExportNotSupported);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    67
 		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    68
 	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    69
 	TUint wordCount = Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    70
 	TUint bytes = (wordCount)*WORD_SIZE;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    71
     
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    72
  	HBufC8* buf = HBufC8::NewMaxLC(bytes);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    73
 	TUint8* bufPtr = (TUint8*)(buf->Ptr());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    74
	TUint8* regPtr = (TUint8*)Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    75
	for(TUint i=0,j=bytes-1; i<bytes; )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    76
 		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    77
 		bufPtr[i++] = regPtr[j--];
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    78
 		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    79
  
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    80
	return buf;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    81
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    82
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    83
/** 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    84
* Gets the number of words required to represent this RInteger.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    85
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    86
* @return	The size of the integer in words.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    87
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    88
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    89
EXPORT_C TUint TInteger::WordCount() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    90
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    91
	return CountWords(Ptr(), Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    92
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    93
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    94
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    95
* Gets the number of bytes required to represent this RInteger.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    96
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    97
* @return	The size of the integer in bytes.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    98
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    99
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   100
EXPORT_C TUint TInteger::ByteCount() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   101
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   102
	TUint wordCount = WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   103
	if(wordCount)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   104
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   105
		return (wordCount-1)*WORD_SIZE + BytePrecision((Ptr())[wordCount-1]);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   106
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   107
	else 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   108
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   109
		return 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   110
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   111
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   112
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   113
/** 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   114
* Get the number of bits required to represent this RInteger.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   115
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   116
* @return	The size of the integer in bits.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   117
* 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   118
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   119
EXPORT_C TUint TInteger::BitCount() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   120
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   121
	TUint wordCount = WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   122
	if(wordCount)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   123
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   124
		return (wordCount-1)*WORD_BITS + BitPrecision(Ptr()[wordCount-1]);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   125
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   126
	else 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   127
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   128
		return 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   129
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   130
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   131
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   132
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   133
//These 3 declarations instantiate a constant 0, 1, 2 for ease of use and
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   134
//quick construction elsewhere in the code.  Note that the functions
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   135
//returning references to this static data return const references as you can't
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   136
//modify the ROM ;)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   137
//word 0: Size of storage in words
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   138
//word 1: Pointer to storage
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   139
//word 2: LSW of storage
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   140
//word 3: MSW of storage
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   141
//Note that the flag bits in word 1 (Ptr()) are zero in the case of a positive
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   142
//stack based integer (SignBit == 0, IsHeapBasedBit == 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   143
const TUint KBigintZero[4] = {2, (TUint)(KBigintZero+2), 0, 0};
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   144
const TUint KBigintOne[4] = {2, (TUint)(KBigintOne+2), 1, 0};
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   145
const TUint KBigintTwo[4] = {2, (TUint)(KBigintTwo+2), 2, 0};
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   146
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   147
/** 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   148
 * Gets the TInteger that represents zero
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   149
 *
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   150
 * @return	The TInteger representing zero
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   151
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   152
EXPORT_C const TInteger& TInteger::Zero(void)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   153
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   154
	return *reinterpret_cast<const TStackInteger64*>(KBigintZero);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   155
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   156
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   157
/** 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   158
 * Gets the TInteger that represents one
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   159
 *
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   160
 * @return	The TInteger representing one
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   161
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   162
EXPORT_C const TInteger& TInteger::One(void)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   163
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   164
	return *reinterpret_cast<const TStackInteger64*>(KBigintOne);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   165
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   166
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   167
/** 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   168
 * Gets the TInteger that represents two
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   169
 *
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   170
 * @return	The TInteger representing two
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   171
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   172
EXPORT_C const TInteger& TInteger::Two(void)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   173
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   174
	return *reinterpret_cast<const TStackInteger64*>(KBigintTwo);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   175
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   176
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   177
EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   178
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   179
	RInteger sum;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   180
    if (NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   181
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   182
        if (aOperand.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   183
            sum = PositiveAddL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   184
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   185
            sum = PositiveSubtractL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   186
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   187
    else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   188
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   189
        if (aOperand.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   190
            sum = PositiveSubtractL(aOperand, *this);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   191
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   192
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   193
            sum = PositiveAddL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   194
			sum.SetSign(TInteger::ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   195
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   196
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   197
	return sum;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   198
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   199
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   200
EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   201
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   202
	RInteger diff;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   203
    if (NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   204
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   205
        if (aOperand.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   206
            diff = PositiveSubtractL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   207
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   208
            diff = PositiveAddL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   209
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   210
    else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   211
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   212
        if (aOperand.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   213
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   214
            diff = PositiveAddL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   215
			diff.SetSign(TInteger::ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   216
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   217
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   218
            diff = PositiveSubtractL(aOperand, *this);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   219
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   220
	return diff;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   221
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   222
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   223
EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   224
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   225
	RInteger product = PositiveMultiplyL(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   226
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   227
	if (NotNegative() != aOperand.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   228
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   229
		product.Negate();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   230
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   231
	return product;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   232
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   233
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   234
EXPORT_C RInteger TInteger::DividedByL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   235
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   236
	RInteger quotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   237
	RInteger remainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   238
	DivideL(remainder, quotient, *this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   239
	remainder.Close();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   240
	return quotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   241
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   242
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   243
EXPORT_C RInteger TInteger::ModuloL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   244
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   245
	RInteger remainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   246
	RInteger quotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   247
	DivideL(remainder, quotient, *this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   248
	quotient.Close();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   249
	return remainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   250
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   251
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   252
EXPORT_C TUint TInteger::ModuloL(TUint aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   253
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   254
	if(!aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   255
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   256
		User::Leave(KErrDivideByZero);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   257
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   258
	return Modulo(*this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   259
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   260
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   261
EXPORT_C RInteger TInteger::ModularMultiplyL(const TInteger& aA, const TInteger& aB,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   262
	const TInteger& aMod) 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   263
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   264
	RInteger product = aA.TimesL(aB);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   265
	CleanupStack::PushL(product);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   266
	RInteger reduced = product.ModuloL(aMod);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   267
	CleanupStack::PopAndDestroy(&product); 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   268
	return reduced;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   269
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   270
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   271
EXPORT_C RInteger TInteger::ModularExponentiateL(const TInteger& aBase, 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   272
	const TInteger& aExp, const TInteger& aMod) 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   273
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   274
	CMontgomeryStructure* mont = CMontgomeryStructure::NewLC(aMod);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   275
	RInteger result = RInteger::NewL(mont->ExponentiateL(aBase, aExp));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   276
	CleanupStack::PopAndDestroy(mont);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   277
	return result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   278
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   279
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   280
EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   281
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   282
	//Binary GCD algorithm -- see HAC 14.4.1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   283
	//with a slight variation -- our g counts shifts rather than actually
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   284
	//shifting.  We then do one shift at the end.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   285
	assert(NotNegative());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   286
	assert(aOperand.NotNegative());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   287
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   288
	RInteger x = RInteger::NewL(*this);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   289
	CleanupStack::PushL(x);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   290
	RInteger y = RInteger::NewL(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   291
	CleanupStack::PushL(y);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   292
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   293
	// 1 Ensure x >= y
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   294
	if( x < y )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   295
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   296
		TClassSwap(x, y);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   297
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   298
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   299
	TUint g = 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   300
	// 2 while x and y even x <- x/2, y <- y/2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   301
	while( x.IsEven() && y.IsEven() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   302
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   303
		x >>= 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   304
		y >>= 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   305
		++g;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   306
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   307
	// 3 while x != 0
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   308
	while( x.NotZero() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   309
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   310
		// 3.1 while x even x <- x/2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   311
		while( x.IsEven() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   312
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   313
			x >>= 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   314
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   315
		// 3.2 while y even y <- y/2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   316
		while( y.IsEven() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   317
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   318
			y >>= 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   319
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   320
		// 3.3 t <- abs(x-y)/2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   321
		RInteger t = x.MinusL(y);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   322
		t >>= 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   323
		t.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   324
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   325
		// 3.4 If x>=y then x <- t else y <- t
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   326
		if( x >= y )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   327
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   328
			x.Set(t);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   329
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   330
		else 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   331
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   332
			y.Set(t);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   333
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   334
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   335
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   336
	// 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   337
	//shifting)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   338
	y <<= g;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   339
	CleanupStack::Pop(&y);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   340
	CleanupStack::PopAndDestroy(&x); 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   341
	return y;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   342
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   343
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   344
EXPORT_C RInteger TInteger::InverseModL(const TInteger& aMod) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   345
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   346
	assert(aMod.NotNegative());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   347
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   348
	RInteger result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   349
	if(IsNegative() || *this>=aMod)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   350
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   351
		RInteger temp = ModuloL(aMod);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   352
		CleanupClosePushL(temp);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   353
		result = temp.InverseModL(aMod);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   354
		CleanupStack::PopAndDestroy(&temp);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   355
		return result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   356
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   357
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   358
	if(aMod.IsEven())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   359
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   360
		if( !aMod || IsEven() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   361
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   362
			return RInteger::NewL(Zero());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   363
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   364
		if( *this == One() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   365
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   366
			return RInteger::NewL(One());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   367
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   368
		RInteger u = aMod.InverseModL(*this); 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   369
		CleanupClosePushL(u);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   370
		if(!u)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   371
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   372
			result = RInteger::NewL(Zero());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   373
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   374
		else 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   375
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   376
			//calculates (aMod*(*this-u)+1)/(*this) 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   377
			result = MinusL(u);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   378
			CleanupClosePushL(result);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   379
			result *= aMod;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   380
			++result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   381
			result /= *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   382
			CleanupStack::Pop(&result); 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   383
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   384
		CleanupStack::PopAndDestroy(&u);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   385
		return result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   386
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   387
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   388
	result = RInteger::NewEmptyL(aMod.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   389
	CleanupClosePushL(result);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   390
	RInteger workspace = RInteger::NewEmptyL(aMod.Size() * 4);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   391
	TUint k = AlmostInverse(result.Ptr(), workspace.Ptr(), Ptr(), Size(),
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   392
		aMod.Ptr(), aMod.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   393
	DivideByPower2Mod(result.Ptr(), result.Ptr(), k, aMod.Ptr(), aMod.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   394
	workspace.Close();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   395
	CleanupStack::Pop(&result);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   396
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   397
	return result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   398
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   399
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   400
EXPORT_C TInteger& TInteger::operator+=(const TInteger& aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   401
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   402
	this->Set(PlusL(aOperand));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   403
    return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   404
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   405
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   406
EXPORT_C TInteger& TInteger::operator-=(const TInteger& aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   407
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   408
	this->Set(MinusL(aOperand));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   409
    return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   410
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   411
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   412
EXPORT_C TInteger& TInteger::operator*=(const TInteger& aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   413
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   414
	this->Set(TimesL(aOperand));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   415
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   416
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   417
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   418
EXPORT_C TInteger& TInteger::operator/=(const TInteger& aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   419
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   420
	this->Set(DividedByL(aOperand));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   421
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   422
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   423
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   424
EXPORT_C TInteger& TInteger::operator%=(const TInteger& aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   425
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   426
	this->Set(ModuloL(aOperand));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   427
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   428
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   429
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   430
EXPORT_C TInteger& TInteger::operator+=(TInt aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   431
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   432
	TStackInteger64 operand(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   433
	*this += operand;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   434
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   435
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   436
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   437
EXPORT_C TInteger& TInteger::operator-=(TInt aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   438
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   439
	TStackInteger64 operand(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   440
	*this -= operand;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   441
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   442
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   443
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   444
EXPORT_C TInteger& TInteger::operator*=(TInt aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   445
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   446
	TStackInteger64 operand(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   447
	*this *= operand;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   448
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   449
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   450
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   451
EXPORT_C TInteger& TInteger::operator--()
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   452
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   453
    if (IsNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   454
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   455
        if (Increment(Ptr(), Size()))
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   456
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   457
            CleanGrowL(2*Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   458
            (Ptr())[Size()/2]=1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   459
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   460
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   461
    else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   462
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   463
        if (Decrement(Ptr(), Size()))
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   464
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   465
			this->CopyL(-1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   466
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   467
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   468
    return *this;	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   469
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   470
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   471
EXPORT_C TInteger& TInteger::operator++()
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   472
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   473
	if(NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   474
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   475
		if(Increment(Ptr(), Size()))
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   476
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   477
			CleanGrowL(2*Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   478
			(Ptr())[Size()/2]=1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   479
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   480
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   481
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   482
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   483
		DecrementNoCarry(Ptr(), Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   484
		if(WordCount()==0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   485
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   486
			this->CopyL(Zero());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   487
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   488
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   489
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   490
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   491
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   492
EXPORT_C TInteger& TInteger::operator <<=(TUint aBits)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   493
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   494
	const TUint wordCount = WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   495
	const TUint shiftWords = aBits / WORD_BITS;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   496
	const TUint shiftBits = aBits % WORD_BITS;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   497
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   498
	CleanGrowL(wordCount+BitsToWords(aBits));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   499
	ShiftWordsLeftByWords(Ptr(), wordCount + shiftWords, shiftWords);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   500
	ShiftWordsLeftByBits(Ptr()+shiftWords, wordCount + BitsToWords(shiftBits), 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   501
		shiftBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   502
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   503
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   504
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   505
EXPORT_C TInteger& TInteger::operator >>=(TUint aBits)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   506
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   507
	const TUint wordCount = WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   508
	const TUint shiftWords = aBits / WORD_BITS;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   509
	const TUint shiftBits = aBits % WORD_BITS;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   510
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   511
	ShiftWordsRightByWords(Ptr(), wordCount, shiftWords);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   512
	if(wordCount > shiftWords)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   513
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   514
		ShiftWordsRightByBits(Ptr(), wordCount - shiftWords, shiftBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   515
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   516
	if(IsNegative() && WordCount()==0) // avoid negative 0
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   517
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   518
		SetSign(EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   519
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   520
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   521
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   522
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   523
EXPORT_C TInt TInteger::UnsignedCompare(const TInteger& aThat) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   524
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   525
	TUint size = WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   526
	TUint thatSize = aThat.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   527
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   528
	if( size == thatSize )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   529
		return Compare(Ptr(), aThat.Ptr(), size);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   530
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   531
		return size > thatSize ? 1 : -1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   532
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   533
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   534
EXPORT_C TInt TInteger::SignedCompare(const TInteger& aThat) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   535
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   536
    if (NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   537
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   538
        if (aThat.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   539
            return UnsignedCompare(aThat);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   540
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   541
            return 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   542
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   543
    else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   544
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   545
        if (aThat.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   546
            return -1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   547
        else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   548
            return -UnsignedCompare(aThat);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   549
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   550
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   551
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   552
EXPORT_C TBool TInteger::operator!() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   553
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   554
	//Ptr()[0] is just a quick way of weeding out non-zero numbers without
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   555
	//doing a full WordCount() == 0.  Very good odds that a non-zero number
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   556
	//will have a bit set in the least significant word
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   557
	return IsNegative() ? EFalse : (Ptr()[0]==0 && WordCount()==0);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   558
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   559
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   560
EXPORT_C TInt TInteger::SignedCompare(TInt aInteger) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   561
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   562
	TStackInteger64 temp(aInteger);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   563
	return SignedCompare(temp);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   564
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   565
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   566
/* TBool IsPrimeL(void) const 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   567
 * and all primality related functions are implemented in primes.cpp */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   568
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   569
EXPORT_C TBool TInteger::Bit(TUint aBitPos) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   570
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   571
	if( aBitPos/WORD_BITS >= Size() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   572
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   573
		return 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   574
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   575
	else 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   576
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   577
		return (((Ptr())[aBitPos/WORD_BITS] >> (aBitPos % WORD_BITS)) & 1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   578
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   579
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   580
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   581
EXPORT_C void TInteger::SetBit(TUint aBitPos) 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   582
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   583
	if( aBitPos/WORD_BITS < Size() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   584
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   585
		ArraySetBit(Ptr(), aBitPos);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   586
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   587
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   588
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   589
EXPORT_C void TInteger::Negate() 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   590
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   591
	if(!!(*this)) //don't flip sign if *this==0
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   592
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   593
		SetSign(TSign((~Sign())&KSignMask));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   594
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   595
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   596
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   597
EXPORT_C void TInteger::CopyL(const TInteger& aInteger, TBool aAllowShrink)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   598
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   599
	if(aAllowShrink)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   600
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   601
		CleanResizeL(aInteger.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   602
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   603
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   604
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   605
		CleanGrowL(aInteger.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   606
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   607
	Construct(aInteger);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   608
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   609
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   610
EXPORT_C void TInteger::CopyL(TInt aInteger, TBool aAllowShrink)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   611
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   612
	if(aAllowShrink)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   613
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   614
		CleanResizeL(2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   615
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   616
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   617
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   618
		CleanGrowL(2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   619
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   620
	Construct(aInteger);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   621
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   622
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   623
EXPORT_C void TInteger::Set(const RInteger& aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   624
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   625
	assert(IsHeapBased());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   626
	Mem::FillZ(Ptr(), WordsToBytes(Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   627
	User::Free(Ptr());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   628
	iPtr = aInteger.iPtr;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   629
	iSize = aInteger.iSize;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   630
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   631
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   632
RInteger TInteger::PositiveAddL(const TInteger &aA, const TInteger& aB) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   633
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   634
	RInteger sum = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   635
	const word aSize = aA.Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   636
	const word bSize = aB.Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   637
	const word* const aReg = aA.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   638
	const word* const bReg = aB.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   639
	word* const sumReg = sum.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   640
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   641
	word carry;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   642
	if (aSize == bSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   643
		carry = Add(sumReg, aReg, bReg, aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   644
	else if (aSize > bSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   645
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   646
		carry = Add(sumReg, aReg, bReg, bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   647
		CopyWords(sumReg+bSize, aReg+bSize, aSize-bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   648
		carry = Increment(sumReg+bSize, aSize-bSize, carry);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   649
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   650
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   651
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   652
		carry = Add(sumReg, aReg, bReg, aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   653
		CopyWords(sumReg+aSize, bReg+aSize, bSize-aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   654
		carry = Increment(sumReg+aSize, bSize-aSize, carry);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   655
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   656
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   657
	if (carry)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   658
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   659
		CleanupStack::PushL(sum);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   660
		sum.CleanGrowL(2*sum.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   661
		CleanupStack::Pop(&sum);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   662
		sum.Ptr()[sum.Size()/2] = 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   663
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   664
	sum.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   665
	return sum;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   666
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   667
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   668
RInteger TInteger::PositiveSubtractL(const TInteger &aA, const TInteger& aB) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   669
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   670
	RInteger diff = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   671
	unsigned aSize = aA.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   672
	aSize += aSize%2;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   673
	unsigned bSize = aB.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   674
	bSize += bSize%2;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   675
	const word* const aReg = aA.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   676
	const word* const bReg = aB.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   677
	word* const diffReg = diff.Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   678
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   679
	if (aSize == bSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   680
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   681
		if (Compare(aReg, bReg, aSize) >= 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   682
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   683
			Subtract(diffReg, aReg, bReg, aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   684
			diff.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   685
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   686
		else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   687
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   688
			Subtract(diffReg, bReg, aReg, aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   689
			diff.SetSign(TInteger::ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   690
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   691
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   692
	else if (aSize > bSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   693
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   694
		word borrow = Subtract(diffReg, aReg, bReg, bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   695
		CopyWords(diffReg+bSize, aReg+bSize, aSize-bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   696
		borrow = Decrement(diffReg+bSize, aSize-bSize, borrow);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   697
		assert(!borrow);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   698
		diff.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   699
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   700
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   701
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   702
		word borrow = Subtract(diffReg, bReg, aReg, aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   703
		CopyWords(diffReg+aSize, bReg+aSize, bSize-aSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   704
		borrow = Decrement(diffReg+aSize, bSize-aSize, borrow);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   705
		assert(!borrow);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   706
		diff.SetSign(TInteger::ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   707
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   708
	return diff;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   709
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   710
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   711
RInteger TInteger::PositiveMultiplyL(const TInteger &aA, const TInteger &aB) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   712
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   713
	unsigned aSize = RoundupSize(aA.WordCount());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   714
	unsigned bSize = RoundupSize(aB.WordCount());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   715
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   716
	RInteger product = RInteger::NewEmptyL(aSize+bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   717
	CleanupClosePushL(product);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   718
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   719
	RInteger workspace = RInteger::NewEmptyL(aSize + bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   720
	AsymmetricMultiply(product.Ptr(), workspace.Ptr(), aA.Ptr(), aSize, aB.Ptr(), 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   721
		bSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   722
	workspace.Close();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   723
	CleanupStack::Pop(&product);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   724
	return product;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   725
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   726
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   727
TUint TInteger::Modulo(const TInteger& aDividend, TUint aDivisor) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   728
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   729
	assert(aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   730
	TUint i = aDividend.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   731
	TUint remainder = 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   732
	while(i--)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   733
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   734
		remainder = TUint(MAKE_DWORD(aDividend.Ptr()[i], remainder) % aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   735
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   736
	return remainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   737
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   738
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   739
void TInteger::PositiveDivideL(RInteger &aRemainder, RInteger &aQuotient,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   740
	const TInteger &aDividend, const TInteger &aDivisor) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   741
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   742
	unsigned dividendSize = aDividend.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   743
	unsigned divisorSize = aDivisor.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   744
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   745
	if (!divisorSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   746
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   747
		User::Leave(KErrDivideByZero);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   748
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   749
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   750
	if (aDividend.UnsignedCompare(aDivisor) == -1)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   751
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   752
		aRemainder.CreateNewL(aDividend.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   753
		CleanupStack::PushL(aRemainder);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   754
		aRemainder.CopyL(aDividend); //set remainder to a
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   755
		aRemainder.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   756
		aQuotient.CleanNewL(2); //Set quotient to zero
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   757
		CleanupStack::Pop(&aRemainder);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   758
		return;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   759
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   760
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   761
	dividendSize += dividendSize%2;	// round up to next even number
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   762
	divisorSize += divisorSize%2;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   763
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   764
	aRemainder.CleanNewL(divisorSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   765
	CleanupStack::PushL(aRemainder);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   766
	aQuotient.CleanNewL(dividendSize-divisorSize+2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   767
	CleanupStack::PushL(aQuotient);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   768
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   769
	RInteger T = RInteger::NewEmptyL(dividendSize+2*divisorSize+4);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   770
	Divide(aRemainder.Ptr(), aQuotient.Ptr(), T.Ptr(), aDividend.Ptr(), 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   771
		dividendSize, aDivisor.Ptr(), divisorSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   772
	T.Close();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   773
	CleanupStack::Pop(2, &aRemainder); //aQuotient, aRemainder
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   774
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   775
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   776
void TInteger::DivideL(RInteger& aRemainder, RInteger& aQuotient, 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   777
	const TInteger& aDividend, const TInteger& aDivisor) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   778
    {
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   779
    PositiveDivideL(aRemainder, aQuotient, aDividend, aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   780
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   781
    if (aDividend.IsNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   782
        {
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   783
        aQuotient.Negate();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   784
        if (aRemainder.NotZero())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   785
            {
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   786
            --aQuotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   787
			assert(aRemainder.Size() <= aDivisor.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   788
			Subtract(aRemainder.Ptr(), aDivisor.Ptr(), aRemainder.Ptr(), 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   789
				aRemainder.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   790
            }
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   791
        }
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   792
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   793
    if (aDivisor.IsNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   794
        aQuotient.Negate();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   795
    }
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   796
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   797
void TInteger::RandomizeL(TUint aBits, TRandomAttribute aAttr)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   798
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   799
	if(!aBits)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   800
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   801
		return;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   802
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   803
	const TUint bytes = BitsToBytes(aBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   804
	const TUint words = BitsToWords(aBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   805
	CleanGrowL(words);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   806
	TPtr8 buf((TUint8*)(Ptr()), bytes, WordsToBytes(Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   807
	TUint bitpos = aBits % BYTE_BITS;
43
9b5a3a9fddf8 Revision: 201007
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents: 17
diff changeset
   808
	TRAPD(err, GenerateRandomBytesL(buf));
9b5a3a9fddf8 Revision: 201007
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents: 17
diff changeset
   809
	if((err != KErrNone) && (err != KErrNotSecure))
9b5a3a9fddf8 Revision: 201007
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents: 17
diff changeset
   810
	    User::Leave(err);
17
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   811
	//mask with 0 all bits above the num requested in the most significant byte
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   812
	if(bitpos)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   813
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   814
		buf[bytes-1] = TUint8( buf[bytes-1] & ((1L << bitpos) - 1) );
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   815
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   816
	//set most significant (top) bit 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   817
	if(aAttr == ETopBitSet || aAttr == ETop2BitsSet)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   818
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   819
		SetBit(aBits-1); //Set bit counts from 0
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   820
		assert(BitCount() == aBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   821
		assert(Bit(aBits-1));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   822
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   823
	//set 2nd bit from top
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   824
	if(aAttr == ETop2BitsSet)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   825
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   826
		SetBit(aBits-2); //Set bit counts from 0
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   827
		assert(BitCount() == aBits);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   828
		assert(Bit(aBits-1));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   829
		assert(Bit(aBits-2));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   830
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   831
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   832
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   833
void TInteger::RandomizeL(const TInteger& aMin, const TInteger& aMax)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   834
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   835
	assert(aMax > aMin);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   836
	assert(aMin.NotNegative());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   837
	RInteger range = RInteger::NewL(aMax);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   838
	CleanupStack::PushL(range);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   839
	range -= aMin;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   840
	const TUint bits = range.BitCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   841
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   842
	//if we find a number < range then aMin+range < aMax 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   843
	do
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   844
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   845
		RandomizeL(bits, EAllBitsRandom);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   846
		} 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   847
	while(*this > range);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   848
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   849
	*this += aMin;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   850
	CleanupStack::PopAndDestroy(&range);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   851
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   852
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   853
/* void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   854
 * and all primality related functions are implemented in primes.cpp */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   855
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   856
void TInteger::CreateNewL(TUint aNewSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   857
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   858
	//should only be called on construction
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   859
	assert(!iPtr);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   860
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   861
	TUint newSize = RoundupSize(aNewSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   862
	SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   863
	SetSize(newSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   864
	SetHeapBased();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   865
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   866
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   867
void TInteger::CleanNewL(TUint aNewSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   868
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   869
	CreateNewL(aNewSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   870
	Mem::FillZ(Ptr(), WordsToBytes(Size())); //clear integer storage
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   871
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   872
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   873
void TInteger::CleanGrowL(TUint aNewSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   874
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   875
	assert(IsHeapBased());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   876
	TUint newSize = RoundupSize(aNewSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   877
	TUint oldSize = Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   878
	if(newSize > oldSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   879
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   880
		TUint* oldPtr = Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   881
		//1) allocate new memory and set ptr and size
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   882
		SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   883
		SetSize(newSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   884
		//2) copy old mem to new mem
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   885
		Mem::Copy(Ptr(), oldPtr, WordsToBytes(oldSize));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   886
		//3) zero all old memory
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   887
		Mem::FillZ(oldPtr, WordsToBytes(oldSize));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   888
		//4) give back old memory
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   889
		User::Free(oldPtr);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   890
		//5) zero new memory from end of copy to end of growth
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   891
		Mem::FillZ(Ptr() + oldSize, WordsToBytes(newSize-oldSize));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   892
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   893
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   894
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   895
void TInteger::CleanResizeL(TUint aNewSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   896
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   897
	assert(IsHeapBased());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   898
	TUint newSize = RoundupSize(aNewSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   899
	TUint oldSize = Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   900
	if(newSize > oldSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   901
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   902
		CleanGrowL(aNewSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   903
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   904
	else if(newSize < oldSize)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   905
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   906
		TUint* oldPtr = Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   907
		//1) zero memory above newsize
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   908
		Mem::FillZ(oldPtr+WordsToBytes(aNewSize),WordsToBytes(oldSize-newSize));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   909
		//2) ReAlloc cell.  Since our newsize is less than oldsize, it is
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   910
		//guarenteed not to move.  Thus this is just freeing part of our old
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   911
		//cell to the heap for other uses.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   912
		SetPtr((TUint*)User::ReAllocL(Ptr(), WordsToBytes(newSize)));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   913
		SetSize(newSize);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   914
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   915
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   916
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   917
EXPORT_C TInteger::TInteger() : iSize(0), iPtr(0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   918
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   919
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   920
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   921
void TInteger::Construct(const TDesC8& aValue)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   922
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   923
	assert(Size() >= BytesToWords(aValue.Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   924
	if(aValue.Size() > 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   925
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   926
		//People write numbers with the most significant digits first (big
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   927
		//endian) but we store our numbers in little endian.  Hence we need to
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   928
		//reverse the string by bytes.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   929
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   930
		TUint bytes = aValue.Size();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   931
		TUint8* i = (TUint8*)Ptr();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   932
		TUint8* j = (TUint8*)aValue.Ptr() + bytes;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   933
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   934
		//Swap the endianess of the number itself
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   935
		// (msb) 01 02 03 04 05 06 (lsb) becomes ->
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   936
		// (lsb) 06 05 04 03 02 01 (msb)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   937
		while( j != (TUint8*)aValue.Ptr() )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   938
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   939
			*i++ = *--j;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   940
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   941
		Mem::FillZ((TUint8*)Ptr() + bytes, WordsToBytes(Size()) - bytes);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   942
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   943
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   944
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   945
		//if size is zero, we zero the whole register
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   946
		Mem::FillZ((TUint8*)Ptr(), WordsToBytes(Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   947
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   948
	SetSign(EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   949
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   950
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   951
void TInteger::Construct(const TInteger& aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   952
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   953
	assert(Size() >= aInteger.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   954
	CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   955
	if(Size() > aInteger.Size())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   956
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   957
		Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   958
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   959
	SetSign(aInteger.Sign());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   960
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   961
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   962
void TInteger::Construct(TInt aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   963
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   964
	Construct((TUint)aInteger);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   965
	if(aInteger < 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   966
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   967
		SetSign(ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   968
		Ptr()[0] = -aInteger;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   969
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   970
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   971
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   972
void TInteger::Construct(TUint aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   973
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   974
	assert(Size() >= 2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   975
	SetSign(EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   976
	Ptr()[0] = aInteger;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   977
	Mem::FillZ(Ptr()+1, WordsToBytes(Size()-1));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   978
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   979
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   980
void TInteger::ConstructStack(TUint aWords, TUint aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   981
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   982
	SetPtr((TUint*)(this)+2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   983
	//SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   984
	SetSize(aWords);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   985
	assert(Size() >= 2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   986
	Ptr()[0] = aInteger;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   987
	Mem::FillZ(&(Ptr()[1]), WordsToBytes(Size()-1));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   988
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   989
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   990
void TInteger::ConstructStack(TUint aWords, const TInteger& aInteger)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   991
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   992
	SetPtr((TUint*)(this)+2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   993
	//SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   994
	SetSize(aWords);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   995
	assert( Size() >= RoundupSize(aInteger.WordCount()) );
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   996
	CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   997
	Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   998
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   999
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1000
// Methods are excluded from coverage due to the problem with BullsEye on ONB.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1001
// Manually verified that these methods are functionally covered.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1002
#ifdef _BullseyeCoverage
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1003
#pragma suppress_warnings on
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1004
#pragma BullseyeCoverage off
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1005
#pragma suppress_warnings off
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1006
#endif
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1007
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1008
EXPORT_C TInteger& TInteger::operator/=(TInt aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1009
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1010
	TStackInteger64 operand(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1011
	*this /= operand;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1012
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1013
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1014
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1015
EXPORT_C TInteger& TInteger::operator%=(TInt aOperand)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1016
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1017
	TStackInteger64 operand(aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1018
	assert(operand.NotNegative());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1019
	*this %= operand;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1020
	return *this;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1021
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1022
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1023
EXPORT_C TInt TInteger::ConvertToLongL(void) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1024
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1025
	if(!IsConvertableToLong())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1026
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1027
		User::Leave(KErrTotalLossOfPrecision);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1028
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1029
	return ConvertToLong();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1030
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1031
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1032
TInt TInteger::ConvertToLong(void) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1033
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1034
	TUint value = ConvertToUnsignedLong();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1035
	return Sign() == EPositive ? value : -(static_cast<TInt>(value));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1036
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1037
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1038
TBool TInteger::IsConvertableToLong(void) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1039
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1040
	if(WordCount() > 1)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1041
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1042
		return EFalse;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1043
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1044
	TUint value = (Ptr())[0];
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1045
	if(Sign() == EPositive)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1046
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1047
		return static_cast<TInt>(value) >= 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1048
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1049
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1050
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1051
		return -(static_cast<TInt>(value)) < 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1052
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1053
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1054
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1055
EXPORT_C RInteger TInteger::SquaredL() const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1056
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1057
	//PositiveMultiplyL optimises for the squaring case already
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1058
	//Any number squared is positive, no need for negative handling in TimesL
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1059
	return PositiveMultiplyL(*this, *this);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1060
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1061
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1062
EXPORT_C RInteger TInteger::DividedByL(TUint aOperand) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1063
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1064
	TUint remainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1065
	RInteger quotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1066
	DivideL(remainder, quotient, *this, aOperand);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1067
	return quotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1068
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1069
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1070
EXPORT_C RInteger TInteger::ExponentiateL(const TInteger& aExponent) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1071
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1072
	//See HAC 14.85
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1073
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1074
	// 1.1 Precomputation
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1075
	// g1 <- g
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1076
	// g2 <- g^2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1077
	RInteger g2 = SquaredL();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1078
	CleanupStack::PushL(g2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1079
	RInteger g1 = RInteger::NewL(*this);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1080
	CleanupStack::PushL(g1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1081
	TWindowSlider slider(aExponent);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1082
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1083
	// 1.2 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1084
	// For i from 1 to (2^(k-1) -1) do g2i+1 <- g2i-1 * g2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1085
	TUint count = (1 << (slider.WindowSize()-1)) - 1; //2^(k-1) -1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1086
	RRArray<RInteger> powerArray(count+1); //+1 because we append g1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1087
	User::LeaveIfError(powerArray.Append(g1));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1088
	CleanupStack::Pop(); //g1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1089
	CleanupClosePushL(powerArray);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1090
	for(TUint k=1; k <= count; k++)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1091
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1092
		RInteger g2iplus1 = g2.TimesL(powerArray[k-1]);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1093
		//This append can't fail as the granularity is set high enough
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1094
		//plus we've already called Append once which will alloc to the 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1095
		//set granularity
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1096
		powerArray.Append(g2iplus1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1097
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1098
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1099
	// 2 A <- 1, i <- t
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1100
	RInteger A = RInteger::NewL(One());
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1101
	CleanupStack::PushL(A);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1102
	TInt i = aExponent.BitCount() - 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1103
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1104
	// 3 While i>=0 do:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1105
	while( i>=0 )
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1106
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1107
		// 3.1 If ei == 0 then A <- A^2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1108
		if(!aExponent.Bit(i))
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1109
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1110
			A *= A;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1111
			i--;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1112
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1113
		// 3.2 Find longest bitstring ei,ei-1,...,el s.t. i-l+1<=k and el==1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1114
		// and do:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1115
		// A <- (A^2^(i-l+1)) * g[the index indicated by the bitstring value]
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1116
		else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1117
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1118
			slider.FindNextWindow(i);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1119
			assert(slider.Length() >= 1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1120
			for(TUint j=0; j<slider.Length(); j++)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1121
				{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1122
				A *= A;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1123
				}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1124
			A *= powerArray[slider.Value()>>1];
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1125
			i -= slider.Length();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1126
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1127
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1128
	CleanupStack::Pop(&A);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1129
	CleanupStack::PopAndDestroy(2, &g2); //powerArray, g2
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1130
	return A;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1131
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1132
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1133
void TInteger::DivideL(TUint& aRemainder, RInteger& aQuotient,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1134
	const TInteger& aDividend, TUint aDivisor) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1135
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1136
	if(!aDivisor)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1137
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1138
		User::Leave(KErrDivideByZero);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1139
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1140
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1141
	TUint i = aDividend.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1142
	aQuotient.CleanNewL(RoundupSize(i));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1143
	PositiveDivide(aRemainder, aQuotient, aDividend, aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1144
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1145
	if(aDividend.NotNegative())
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1146
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1147
		aQuotient.SetSign(TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1148
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1149
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1150
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1151
		aQuotient.SetSign(TInteger::ENegative);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1152
		if(aRemainder)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1153
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1154
			--aQuotient;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1155
			aRemainder = aDivisor = aRemainder;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1156
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1157
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1158
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1159
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1160
void TInteger::PositiveDivide(TUint& aRemainder, TInteger& aQuotient, 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1161
	const TInteger& aDividend, TUint aDivisor) const
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1162
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1163
	assert(aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1164
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1165
	TUint i = aDividend.WordCount();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1166
	assert(aQuotient.Size() >= RoundupSize(i));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1167
	assert(aQuotient.Sign() == TInteger::EPositive);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1168
	aRemainder = 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1169
	while(i--)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1170
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1171
		aQuotient.Ptr()[i] = 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1172
			TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) / aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1173
		aRemainder = 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1174
			TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) % aDivisor);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1175
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
  1176
	}