anchor.diff:  {   2017-01-15: Reworked SetBit, ClearBit and FlipBit.                       }
   {                                                                            }
   {   2017-07-14: Changed all manual aligns to use .ALIGN 16                   }
  +{                                                                            }
  +{   2017-08-17: Removed buffer overflow bugs in InternalMultiplyAndAdd16 and }
  +{               UncheckedDivModKnuth. Also removed bug from                  }
  +{               InternalShiftLeft. All after using FastMM4 in full debug     }
  +{               mode (which adds extra footer bytes to every allocation).    }
  +{                                                                            }
   {----------------------------------------------------------------------------}
  +{   Also see GitHub commit comments.                                         }
  +{----------------------------------------------------------------------------}
   
   unit Velthuis.BigIntegers;
  +
  +{///////////////////////////////////////////////////////////////////////////////////////////////
  +
  +   FastMM4 complains about buffer overruns (corrupted block footers)
  +   =================================================================
  +
  +   - Got rid of the one in TryParse, caused by InternalMultiplyAndAdd16.
  +   - Got rid of the one in UncheckedDivModKnuth.
  +   - Must update InternalMultiplyAndAdd32 too (code almost the same as InternalMultiplyAndAdd16).
  +   - Must revert TryParse(... Base, ...) to old version and check that too.
  +
  + ///////////////////////////////////////////////////////////////////////////////////////////////}
   
   { TODO:
     - Remove local BigIntegers where possible. Removing Res from class function BigInteger.Add sped
  
positive.code:     /// <param name="Value">The resulting BigInteger, if the parsing succeeds. Value is undefined if the
      ///   parsing fails.</param>
      /// <returns>Returns True if S could be parsed into a valid BigInteger in Res. Returns False on failure.</returns>
      class function TryParse(const S: string; Base: TNumberBase; out Value: BigInteger): Boolean; overload; static;
  
      // -------------------------------------------------------------------------------------------------------------//
      // Note: most of the parse format for BigIntegers was taken from or inspired by Common Lisp (e.g. '%nnR' or     //
  
negative.code:   LExtra: Word;
    LMultiplicator: Word;
    LProduct: Cardinal;
    LResult: PLimb;
  asm
          PUSH    EBX
          PUSH    ESI
          PUSH    EDI
  
          MOV     ESI,EAX
          MOV     EDI,[EDX]
          MOV     LLength,ECX
          MOV     LResult,EDI
          XOR     EBX,EBX
  
  @MultLoop:
  
          MOV     EAX,[ESI]
          MOVZX   EDX,Multiplicator
          MUL     EDX
          ADD     EAX,EBX
          ADC     EDX,0
          MOV     EBX,EDX
          MOV     [EDI],EAX
          LEA     ESI,[ESI + CLimbSize]
          LEA     EDI,[EDI + CLimbSize]
          LEA     ECX,[ECX - 1]
          JECXZ   @EndMultLoop
          JMP     @MultLoop
  
  @EndMultLoop:
  
          MOV     [EDI],EBX
  
          MOV     ECX,LLength
          MOVZX   EBX,Addend
          OR      EBX,EBX
          JE      @Exit
          MOV     EDI,LResult
          CLC
  
  @AddLoop:
  
          ADC     [EDI],EBX
          JNC     @Exit
          MOV     EBX,0
          LEA     EDI,[EDI + CLimbSize]
          LEA     ECX,[ECX - 1]
          JECXZ   @Exit
          JMP     @AddLoop
  
  @Exit:
  
          POP     EDI
          POP     ESI
          POP     EBX
  end;
  {$ELSE WIN64}
  asm
          .PUSHNV RBX
          .PUSHNV RDI
          .PUSHNV RSI
  
          MOVZX   R10D,Addend             // R10D = Addend
          MOV     R11,[RDX]               // R11 = SaveResult
          MOV     RDI,R11                 // RDI = Result
          MOV     RSI,RCX                 // RSI = Multiplicand
          MOV     ECX,R8D                 // ECX = MSize
          JECXZ   @SkipMult
          OR      R9D,R9D                 // R9D = Multiplicator
          JE      @SkipMult
          XOR     EBX,EBX                 // EBX = Carry
  
  @MultLoop:
  
          MOV     EAX,[RSI]
          MUL     EAX,R9D                 // Unusual syntax, but XE2 otherwise generates MUL R9 instead of MUL R9D
          ADD     EAX,EBX
          ADC     EDX,0
          MOV     [RDI],EAX
          MOV     EBX,EDX
          LEA     RSI,[RSI + CLimbSize]
          LEA     RDI,[RDI + CLimbSize]
          LEA     ECX,[ECX - 1]
          JECXZ   @EndMultLoop
          JMP     @MultLoop
  
  @EndMultLoop:
  
          MOV     [RDI],EBX
  
  @SkipMult:
  
          MOV     RDI,R11
          MOV     ECX,R8D
  
          ADD     [RDI],R10D
          JNC     @Exit
          LEA     RDI,[RDI + CLimbSize]
          LEA     ECX,[ECX-1]
          JECXZ   @Exit
          MOV     R10D,0
  
  @CarryLoop:
  
          ADC     [RDI],R10D
          JNC     @Exit
          LEA     RDI,[RDI + CLimbSize]
          LEA     ECX,[ECX - 1]
          JECXZ   @Exit
          JMP     @CarryLoop
  
  @Exit:
  end;
  {$IFEND}
  
  
  
  class operator BigInteger.Multiply(const Left: BigInteger; Right: Word): BigInteger;
  var
    ResData: TMagnitude;
    ResSize: Integer;
  begin
    if (Right = 0) or ((Left.FSize and SizeMask) = 0) then
      Exit(Zero);
    ResSize := (Left.FSize and SizeMask) + 2;
    SetLength(ResData, ResSize);
    InternalMultiplyAndAdd16(Left.FData, ResData, (Left.FSize and SizeMask), Right, 0);
    Assert(Result.FData <> ResData);
    //Deliberate error: After InternalMultiplyAndAdd16, ResData is invalid.
    Result.FData := ResData;
    Result.FSize := (Left.FSize and SignMask) or ResSize;
    Result.Compact;
  end;
  
  class operator BigInteger.Multiply(Left: Word; const Right: BigInteger): BigInteger;
  begin
    Result := Multiply(Right, Left);
  end;
  
  class procedure BigInteger.MultiplyKaratsuba(const Left, Right: BigInteger; var Result: BigInteger);
  