internal void DoSquare( Integer ToSquare ) { if( ToSquare.GetIndex() == 0 ) { ToSquare.Square0(); return; } if( ToSquare.GetIndex() == 1 ) { ToSquare.Square1(); return; } if( ToSquare.GetIndex() == 2 ) { ToSquare.Square2(); return; } // Now Index is at least 3: int DoubleIndex = ToSquare.GetIndex() << 1; if( DoubleIndex >= Integer.DigitArraySize ) { throw( new Exception( "Square() overflowed." )); } for( int Row = 0; Row <= ToSquare.GetIndex(); Row++ ) { if( ToSquare.GetD( Row ) == 0 ) { for( int Column = 0; Column <= ToSquare.GetIndex(); Column++ ) M[Column + Row, Row] = 0; } else { for( int Column = 0; Column <= ToSquare.GetIndex(); Column++ ) M[Column + Row, Row] = ToSquare.GetD( Row ) * ToSquare.GetD( Column ); } } // Add the columns up with a carry. ToSquare.SetD( 0, M[0, 0] & 0xFFFFFFFF ); ulong Carry = M[0, 0] >> 32; for( int Column = 1; Column <= DoubleIndex; Column++ ) { ulong TotalLeft = 0; ulong TotalRight = 0; for( int Row = 0; Row <= Column; Row++ ) { if( Row > ToSquare.GetIndex() ) break; if( Column > (ToSquare.GetIndex() + Row) ) continue; TotalRight += M[Column, Row] & 0xFFFFFFFF; TotalLeft += M[Column, Row] >> 32; } TotalRight += Carry; ToSquare.SetD( Column, TotalRight & 0xFFFFFFFF ); Carry = TotalRight >> 32; Carry += TotalLeft; } ToSquare.SetIndex( DoubleIndex ); if( Carry != 0 ) { ToSquare.SetIndex( ToSquare.GetIndex() + 1 ); if( ToSquare.GetIndex() >= Integer.DigitArraySize ) throw( new Exception( "Square() overflow." )); ToSquare.SetD( ToSquare.GetIndex(), Carry ); } }