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