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 IsNegative: Boolean read FIsNegative;
|
||||||
property Sign: Integer read GetSign;
|
property Sign: Integer read GetSign;
|
||||||
class property Zero: TBigInt read GetZero;
|
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 CompareTo(constref AOther: TBigInt): Integer;
|
||||||
function TryToInt64(out AOutput: Int64): Boolean;
|
function TryToInt64(out AOutput: Int64): Boolean;
|
||||||
// TODO: ToString is currently for debug output only.
|
// TODO: ToString is currently for debug output only.
|
||||||
|
@ -461,6 +465,21 @@ begin
|
||||||
Result := StrToDWord(part);
|
Result := StrToDWord(part);
|
||||||
end;
|
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;
|
function TBigInt.CompareTo(constref AOther: TBigInt): Integer;
|
||||||
begin
|
begin
|
||||||
if FIsNegative = AOther.FIsNegative then
|
if FIsNegative = AOther.FIsNegative then
|
||||||
|
@ -549,6 +568,7 @@ end;
|
||||||
operator := (const A: Int64): TBigInt;
|
operator := (const A: Int64): TBigInt;
|
||||||
begin
|
begin
|
||||||
Result := TBigInt.FromInt64(A);
|
Result := TBigInt.FromInt64(A);
|
||||||
|
//WriteLn(':=a op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator - (const A: TBigInt): TBigInt;
|
operator - (const A: TBigInt): TBigInt;
|
||||||
|
@ -563,6 +583,8 @@ begin
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result := TBigInt.Zero;
|
Result := TBigInt.Zero;
|
||||||
|
//WriteLn(' a: ', A.ToString);
|
||||||
|
//WriteLn('-a op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator + (const A, B: TBigInt): TBigInt;
|
operator + (const A, B: TBigInt): TBigInt;
|
||||||
|
@ -571,6 +593,9 @@ begin
|
||||||
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative)
|
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative)
|
||||||
else
|
else
|
||||||
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative);
|
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative);
|
||||||
|
//WriteLn(' a: ', A.ToString);
|
||||||
|
//WriteLn(' b: ', B.ToString);
|
||||||
|
//WriteLn('a+b op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator - (const A, B: TBigInt): TBigInt;
|
operator - (const A, B: TBigInt): TBigInt;
|
||||||
|
@ -579,6 +604,9 @@ begin
|
||||||
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative)
|
Result := TBigInt.SubtractAbsoluteValues(A, B, A.IsNegative)
|
||||||
else
|
else
|
||||||
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative);
|
Result := TBigInt.AddAbsoluteValues(A, B, A.IsNegative);
|
||||||
|
//WriteLn(' a: ', A.ToString);
|
||||||
|
//WriteLn(' b: ', B.ToString);
|
||||||
|
//WriteLn('a-b op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator * (const A, B: TBigInt): TBigInt;
|
operator * (const A, B: TBigInt): TBigInt;
|
||||||
|
@ -587,6 +615,9 @@ begin
|
||||||
Result := TBigInt.Zero
|
Result := TBigInt.Zero
|
||||||
else
|
else
|
||||||
Result := TBigInt.MultiplyAbsoluteValues(A, B, A.IsNegative <> B.IsNegative);
|
Result := TBigInt.MultiplyAbsoluteValues(A, B, A.IsNegative <> B.IsNegative);
|
||||||
|
//WriteLn(' a: ', A.ToString);
|
||||||
|
//WriteLn(' b: ', B.ToString);
|
||||||
|
//WriteLn('a*b op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator shl(const A: TBigInt; const B: Integer): TBigInt;
|
operator shl(const A: TBigInt; const B: Integer): TBigInt;
|
||||||
|
@ -639,6 +670,8 @@ begin
|
||||||
|
|
||||||
Result.FIsNegative := A.IsNegative;
|
Result.FIsNegative := A.IsNegative;
|
||||||
end;
|
end;
|
||||||
|
//WriteLn(' a: ', A.ToString);
|
||||||
|
//WriteLn('a<< op: ', Result.ToString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator = (const A, B: TBigInt): Boolean;
|
operator = (const A, B: TBigInt): Boolean;
|
||||||
|
|
|
@ -70,6 +70,17 @@ type
|
||||||
procedure TestLongNegative;
|
procedure TestLongNegative;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TBigIntMostSignificantBitIndexTestCase }
|
||||||
|
|
||||||
|
TBigIntMostSignificantBitIndexTestCase = class(TTestCase)
|
||||||
|
private
|
||||||
|
procedure Test(const ABinValue: string; const AExpectedIndex: Int64);
|
||||||
|
published
|
||||||
|
procedure TestZero;
|
||||||
|
procedure TestShort;
|
||||||
|
procedure TestLong;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TBigIntFromInt64TestCase }
|
{ TBigIntFromInt64TestCase }
|
||||||
|
|
||||||
TBigIntFromInt64TestCase = class(TTestCase)
|
TBigIntFromInt64TestCase = class(TTestCase)
|
||||||
|
@ -271,6 +282,37 @@ begin
|
||||||
Test('-192648F1305DD04757A24C873F29F60B6184B5', -1);
|
Test('-192648F1305DD04757A24C873F29F60B6184B5', -1);
|
||||||
end;
|
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 }
|
{ TBigIntFromInt64TestCase }
|
||||||
|
|
||||||
procedure TBigIntFromInt64TestCase.Test(const AValue: Int64);
|
procedure TBigIntFromInt64TestCase.Test(const AValue: Int64);
|
||||||
|
@ -903,6 +945,7 @@ end;
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
RegisterTest(TBigIntSignTestCase);
|
RegisterTest(TBigIntSignTestCase);
|
||||||
|
RegisterTest(TBigIntMostSignificantBitIndexTestCase);
|
||||||
RegisterTest(TBigIntFromInt64TestCase);
|
RegisterTest(TBigIntFromInt64TestCase);
|
||||||
RegisterTest(TBigIntFromHexTestCase);
|
RegisterTest(TBigIntFromHexTestCase);
|
||||||
RegisterTest(TBigIntFromBinTestCase);
|
RegisterTest(TBigIntFromBinTestCase);
|
||||||
|
|
Loading…
Reference in New Issue