Added TBigInt.GetMostSignificantBitIndex and tests
This commit is contained in:
parent
2ca960f19c
commit
52cee73123
33
UBigInt.pas
33
UBigInt.pas
|
@ -76,6 +76,10 @@ type
|
|||
property IsNegative: Boolean read FIsNegative;
|
||||
property Sign: Integer read GetSign;
|
||||
class property Zero: TBigInt read GetZero;
|
||||
|
||||
// Returns the index of the most significant bit, i.e. returns integer k, where 2^k is the largest power of 2 that
|
||||
// is less than or equal to the absolute value of the number itself. Returns -1 if the given number is 0.
|
||||
function GetMostSignificantBitIndex: Int64;
|
||||
function CompareTo(constref AOther: TBigInt): Integer;
|
||||
function TryToInt64(out AOutput: Int64): Boolean;
|
||||
// TODO: ToString is currently for debug output only.
|
||||
|
@ -461,6 +465,21 @@ begin
|
|||
Result := StrToDWord(part);
|
||||
end;
|
||||
|
||||
function TBigInt.GetMostSignificantBitIndex: Int64;
|
||||
var
|
||||
high, i: Integer;
|
||||
begin
|
||||
high := Length(FDigits) - 1;
|
||||
if (high = 0) and (FDigits[0] = 0) then
|
||||
Result := -1
|
||||
else begin
|
||||
i := CBitsPerDigit - 1;
|
||||
while ((1 << i) and FDigits[high]) = 0 do
|
||||
Dec(i);
|
||||
Result := high * CBitsPerDigit + i;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBigInt.CompareTo(constref AOther: TBigInt): Integer;
|
||||
begin
|
||||
if FIsNegative = AOther.FIsNegative then
|
||||
|
@ -549,6 +568,7 @@ end;
|
|||
operator := (const A: Int64): TBigInt;
|
||||
begin
|
||||
Result := TBigInt.FromInt64(A);
|
||||
//WriteLn(':=a op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator - (const A: TBigInt): TBigInt;
|
||||
|
@ -563,6 +583,8 @@ begin
|
|||
end
|
||||
else
|
||||
Result := TBigInt.Zero;
|
||||
//WriteLn(' a: ', A.ToString);
|
||||
//WriteLn('-a op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator + (const A, B: TBigInt): TBigInt;
|
||||
|
@ -571,6 +593,9 @@ begin
|
|||
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative)
|
||||
else
|
||||
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative);
|
||||
//WriteLn(' a: ', A.ToString);
|
||||
//WriteLn(' b: ', B.ToString);
|
||||
//WriteLn('a+b op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator - (const A, B: TBigInt): TBigInt;
|
||||
|
@ -579,6 +604,9 @@ begin
|
|||
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative)
|
||||
else
|
||||
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative);
|
||||
//WriteLn(' a: ', A.ToString);
|
||||
//WriteLn(' b: ', B.ToString);
|
||||
//WriteLn('a-b op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator * (const A, B: TBigInt): TBigInt;
|
||||
|
@ -587,6 +615,9 @@ begin
|
|||
Result := TBigInt.Zero
|
||||
else
|
||||
Result := TBigInt.MultiplyAbsoluteValues(A, B, A.IsNegative <> B.IsNegative);
|
||||
//WriteLn(' a: ', A.ToString);
|
||||
//WriteLn(' b: ', B.ToString);
|
||||
//WriteLn('a*b op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator shl(const A: TBigInt; const B: Integer): TBigInt;
|
||||
|
@ -639,6 +670,8 @@ begin
|
|||
|
||||
Result.FIsNegative := A.IsNegative;
|
||||
end;
|
||||
//WriteLn(' a: ', A.ToString);
|
||||
//WriteLn('a<< op: ', Result.ToString);
|
||||
end;
|
||||
|
||||
operator = (const A, B: TBigInt): Boolean;
|
||||
|
|
|
@ -70,6 +70,17 @@ type
|
|||
procedure TestLongNegative;
|
||||
end;
|
||||
|
||||
{ TBigIntMostSignificantBitIndexTestCase }
|
||||
|
||||
TBigIntMostSignificantBitIndexTestCase = class(TTestCase)
|
||||
private
|
||||
procedure Test(const ABinValue: string; const AExpectedIndex: Int64);
|
||||
published
|
||||
procedure TestZero;
|
||||
procedure TestShort;
|
||||
procedure TestLong;
|
||||
end;
|
||||
|
||||
{ TBigIntFromInt64TestCase }
|
||||
|
||||
TBigIntFromInt64TestCase = class(TTestCase)
|
||||
|
@ -271,6 +282,37 @@ begin
|
|||
Test('-192648F1305DD04757A24C873F29F60B6184B5', -1);
|
||||
end;
|
||||
|
||||
{ TBigIntMostSignificantBitIndexTestCase }
|
||||
|
||||
procedure TBigIntMostSignificantBitIndexTestCase.Test(const ABinValue: string; const AExpectedIndex: Int64);
|
||||
var
|
||||
a: TBigInt;
|
||||
begin
|
||||
a := TBigInt.FromBinaryString(ABinValue);
|
||||
AssertEquals('BigInt from binary string ''' + ABinValue + ''' did not have its most significant bit at index '''
|
||||
+ IntToStr(AExpectedIndex) + '''.',
|
||||
AExpectedIndex, a.GetMostSignificantBitIndex);
|
||||
end;
|
||||
|
||||
procedure TBigIntMostSignificantBitIndexTestCase.TestZero;
|
||||
begin
|
||||
Test('0', -1);
|
||||
end;
|
||||
|
||||
procedure TBigIntMostSignificantBitIndexTestCase.TestShort;
|
||||
begin
|
||||
Test('1', 0);
|
||||
Test('11111101111001', 13);
|
||||
Test('10010111101100001110110101111000', 31);
|
||||
end;
|
||||
|
||||
procedure TBigIntMostSignificantBitIndexTestCase.TestLong;
|
||||
begin
|
||||
Test('111100010101010100011101010100011', 32);
|
||||
Test('11101001101010111101000101010001010101010101111111001010101010010100101000101011111001000111001001100011', 103);
|
||||
Test('111101100011110110111011010111100000000001010111101110101101101100101010110111101011010101001100', 95);
|
||||
end;
|
||||
|
||||
{ TBigIntFromInt64TestCase }
|
||||
|
||||
procedure TBigIntFromInt64TestCase.Test(const AValue: Int64);
|
||||
|
@ -903,6 +945,7 @@ end;
|
|||
initialization
|
||||
|
||||
RegisterTest(TBigIntSignTestCase);
|
||||
RegisterTest(TBigIntMostSignificantBitIndexTestCase);
|
||||
RegisterTest(TBigIntFromInt64TestCase);
|
||||
RegisterTest(TBigIntFromHexTestCase);
|
||||
RegisterTest(TBigIntFromBinTestCase);
|
||||
|
|
Loading…
Reference in New Issue