Skip to content

Commit f160496

Browse files
committed
Add tests for 3 new Maths functions
Added unit tests for DigitSumBase, DigitCountBase & DigitsOf to TestUMathsCatSnippets unit. Regenerated UMathsCatSnippets from CodeSnip to include the 3 new units.
1 parent ac6f54d commit f160496

File tree

2 files changed

+220
-7
lines changed

2 files changed

+220
-7
lines changed

tests/Cat-Maths/TestUMathsCatSnippets.pas

+115-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
interface
44

55
uses
6-
Types, Math, TestFramework, UMathsCatSnippets;
6+
Types, Math, SysUtils, TestFramework, UMathsCatSnippets;
77

88
type
99
TestMathsCatSnippets = class(TTestCase)
@@ -18,7 +18,10 @@ TestMathsCatSnippets = class(TTestCase)
1818
procedure TestWeightedArithMean_Double_Except2;
1919
procedure TestWeightedArithMean_Double_Except3;
2020
procedure TestWeightedArithMean_Double_Except4;
21-
21+
procedure TestDigitSumBase_Except;
22+
procedure TestDigitsOf_ArgExcept;
23+
function EqualArrays(const Left, Right: TBytes): Boolean;
24+
function ReverseArray(const A: TBytes): TBytes;
2225
published
2326
procedure TestDigitCount;
2427
procedure TestDigitCount2;
@@ -68,17 +71,16 @@ TestMathsCatSnippets = class(TTestCase)
6871
procedure TestArithMean_Integer;
6972
procedure TestArithMean_Cardinal;
7073
procedure TestArithMean_Double;
71-
7274
procedure TestWeightedArithMean_Integer;
7375
procedure TestWeightedArithMean_Cardinal;
7476
procedure TestWeightedArithMean_Double;
77+
procedure TestDigitCountBase;
78+
procedure TestDigitSumBase;
79+
procedure TestDigitsOf;
7580
end;
7681

7782
implementation
7883

79-
uses
80-
SysUtils;
81-
8284
const
8385
First100Primes: array[1..100] of Int64 = (
8486
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
@@ -185,6 +187,27 @@ function RectHeight(const Rect: TRect): Integer;
185187

186188
{ TestMathsCatSnippets }
187189

190+
function TestMathsCatSnippets.EqualArrays(const Left, Right: TBytes): Boolean;
191+
var
192+
Idx: Integer;
193+
begin
194+
Result := True;
195+
if Length(Left) <> Length(Right) then
196+
Exit(False);
197+
for Idx := Low(Left) to High(Left) do
198+
if Left[Idx] <> Right[Idx] then
199+
Exit(False);
200+
end;
201+
202+
function TestMathsCatSnippets.ReverseArray(const A: TBytes): TBytes;
203+
var
204+
I: Integer;
205+
begin
206+
SetLength(Result, Length(A));
207+
for I := 0 to High(A) do
208+
Result[High(A)-I] := A[I];
209+
end;
210+
188211
procedure TestMathsCatSnippets.StretchRect_A_Except1;
189212
var
190213
R0, R1: TRect;
@@ -364,6 +387,23 @@ procedure TestMathsCatSnippets.TestDigitCount2;
364387
CheckEquals(5, DigitCount2(-12345), 'DigitCount2(-12345)');
365388
end;
366389

390+
procedure TestMathsCatSnippets.TestDigitCountBase;
391+
begin
392+
CheckEquals(1, DigitCountBase(0, 10), '0 base 10');
393+
CheckEquals(1, DigitCountBase(1, 10), '1 base 10');
394+
CheckEquals(2, DigitCountBase(9, 8), '9 base 8');
395+
CheckEquals(2, DigitCountBase(-9, 8), '9 base 8');
396+
CheckEquals(2, DigitCountBase(9, 7), '9 base 7');
397+
CheckEquals(1, DigitCountBase(9, 16), '9 base 16');
398+
CheckEquals(2, DigitCountBase(12, 10), '12 base 10');
399+
CheckEquals(4, DigitCountBase(12, 2), '12 base 2');
400+
CheckEquals(5, DigitCountBase(123456, 16), '123456 base 16');
401+
CheckEquals(11, DigitCountBase(1234567890, 8), '1234567890 base 8');
402+
CheckEquals(2, DigitCountBase(256, 255), '256 base 255');
403+
CheckEquals(9, DigitCountBase(-429981696, 12), '-429981696 base 12');
404+
CheckEquals(8, DigitCountBase($FFFFFFFF, 16), '$FFFFFFFF base 16');
405+
end;
406+
367407
procedure TestMathsCatSnippets.TestDigitCountR;
368408
begin
369409
CheckEquals(1, DigitCountR(0), 'DigitCountR(0)');
@@ -376,6 +416,57 @@ procedure TestMathsCatSnippets.TestDigitCountR;
376416
CheckEquals(5, DigitCountR(-12345), 'DigitCountR(-12345)');
377417
end;
378418

419+
procedure TestMathsCatSnippets.TestDigitsOf;
420+
var
421+
E: TBytes;
422+
begin
423+
E := TBytes.Create(0);
424+
CheckTrue(EqualArrays(E, DigitsOf(0, 10)), '0, base 10');
425+
CheckTrue(EqualArrays(E, DigitsOf(0, 16)), '0, base 16');
426+
E := ReverseArray(TBytes.Create(3, 6, 5, 7, 0, 4, 2, 1, 0));
427+
CheckTrue(EqualArrays(E, DigitsOf(365704210, 10)), '365704210, base 10');
428+
E := ReverseArray(TBytes.Create(1, 5, $C, $C, 3, 4, 1, 2));
429+
CheckTrue(EqualArrays(E, DigitsOf(365704210, 16)), '365704210, base 16');
430+
E := ReverseArray(TBytes.Create({0,0,0}1, 0,1,0,1, 1,1,0,0, 1,1,0,0, 0,0,1,1, 0,1,0,0, 0,0,0,1, 0,0,1,0));
431+
CheckTrue(EqualArrays(E, DigitsOf(365704210, 2)), '365704210, base 2');
432+
E := TBytes.Create(7);
433+
CheckTrue(EqualArrays(E, DigitsOf(7, 8)), '7, base 8');
434+
E := ReverseArray(TBytes.Create(1,3));
435+
CheckTrue(EqualArrays(E, DigitsOf(7, 4)), '7, base 4');
436+
E := ReverseArray(TBytes.Create(1,6));
437+
CheckTrue(EqualArrays(E, DigitsOf(16, 10)), '16, base 10');
438+
E := ReverseArray(TBytes.Create(1,0));
439+
CheckTrue(EqualArrays(E, DigitsOf(16, 16)), '16, base 16');
440+
E := TBytes.Create(16);
441+
CheckTrue(EqualArrays(E, DigitsOf(16, 32)), '16, base 32');
442+
E := ReverseArray(TBytes.Create(1,5));
443+
CheckTrue(EqualArrays(E, DigitsOf(15, 10)), '15, base 10');
444+
E := TBytes.Create(15);
445+
CheckTrue(EqualArrays(E, DigitsOf(15, 16)), '15, base 16');
446+
E := TBytes.Create(3);
447+
CheckTrue(EqualArrays(E, DigitsOf(3, 10)), '3, base 10');
448+
E := ReverseArray(TBytes.Create(1,0));
449+
CheckTrue(EqualArrays(E, DigitsOf(3, 3)), '3, base 3');
450+
E := ReverseArray(TBytes.Create(1,1));
451+
CheckTrue(EqualArrays(E, DigitsOf(3, 2)), '3, base 2');
452+
E := ReverseArray(TBytes.Create(1,254));
453+
CheckTrue(EqualArrays(E, DigitsOf(509, 255)), '509, base 255');
454+
E := ReverseArray(TBytes.Create(4,2,9,4,9,6,7,2,9,5));
455+
CheckTrue(EqualArrays(E, DigitsOf(4294967295, 10)), 'High(Cardinal), base 10');
456+
E := TBytes.Create($f,$f,$f,$f,$f,$f,$f,$f);
457+
CheckTrue(EqualArrays(E, DigitsOf($FFFFFFFF, 16)), 'High(Cardinal), base 16');
458+
E := ReverseArray(TBytes.Create(4,7,6,8,7,3,6,2));
459+
CheckTrue(EqualArrays(E, DigitsOf(-47687362, 10)), '-47687362, base 10');
460+
E := TBytes.Create(1,1);
461+
CheckTrue(EqualArrays(E, DigitsOf(-17, 16)), '-17, base 16');
462+
CheckException(TestDigitsOf_ArgExcept, EArgumentException, 'Argument Exception');
463+
end;
464+
465+
procedure TestMathsCatSnippets.TestDigitsOf_ArgExcept;
466+
begin
467+
DigitsOf(2345, 0);
468+
end;
469+
379470
procedure TestMathsCatSnippets.TestDigitSum;
380471
begin
381472
CheckEquals(0, DigitSum(0), 'DigitSum(0)');
@@ -392,6 +483,24 @@ procedure TestMathsCatSnippets.TestDigitSum;
392483
CheckEquals(-9, DigitSum(-9), 'DigitSum(-9)');
393484
end;
394485

486+
procedure TestMathsCatSnippets.TestDigitSumBase;
487+
begin
488+
CheckEquals(6, DigitSumBase(123, 10), '123 base 10');
489+
CheckEquals(18, DigitSumBase(123, 16), '123 base 16 (7B)');
490+
CheckEquals(6, DigitSumBase(123, 2), '123 base 2 (0111 1011)');
491+
CheckEquals(7, DigitSumBase(1785, 255), '1785 base 255 (70)');
492+
CheckEquals(17, DigitSumBase(512, 100), '512 base 100 (5,12)');
493+
CheckEquals(0, DigitSumBase(0, 32), '0 base 32');
494+
CheckEquals(8*$f, DigitSumBase($FFFFFFFF, 16), '$FFFFFFFF base 16');
495+
CheckEquals(-45, DigitSumBase(-9876543210, 10), '-9876543210 base 10');
496+
CheckException(TestDigitSumBase_Except, EArgumentException, 'Err: base 1');
497+
end;
498+
499+
procedure TestMathsCatSnippets.TestDigitSumBase_Except;
500+
begin
501+
DigitSumBase(42, 1);
502+
end;
503+
395504
procedure TestMathsCatSnippets.TestGCD;
396505
begin
397506
CheckEquals(1, GCD(1,1), 'GCD(1,1)');

tests/Cat-Maths/UMathsCatSnippets.pas

+105-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* The unit is copyright © 2005-2024 by Peter Johnson & Contributors and is
77
* licensed under the MIT License (https://opensource.org/licenses/MIT).
88
*
9-
* Generated on : Sun, 05 Jan 2025 17:16:31 GMT.
9+
* Generated on : Tue, 07 Jan 2025 13:13:01 GMT.
1010
* Generated by : DelphiDabbler CodeSnip Release 4.24.0.
1111
*
1212
* The latest version of CodeSnip is available from the CodeSnip GitHub project
@@ -117,16 +117,41 @@ function DigitCount(AInteger: Int64): Integer;
117117
}
118118
function DigitCount2(const AValue: Int64): Integer;
119119

120+
{
121+
Returns the number of digits in integer N when expressed in base Base.
122+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
123+
exception is raised.
124+
}
125+
function DigitCountBase(N: Int64; const Base: Byte): Cardinal;
126+
120127
{
121128
Counts the number of digits in the given integer using recursion.
122129
}
123130
function DigitCountR(AValue: Int64): Integer;
124131

132+
{
133+
Returns an array containing the digits of integer N when expressed in base
134+
Base. The array is ordered with the least significant digit first.
135+
The returned array contains the decimal value of the digit, for e.g. the hex
136+
symbol F is represented by an array element containing the value 15.
137+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
138+
exception is raised.
139+
}
140+
function DigitsOf(N: Int64; const Base: Byte): SysUtils.TBytes;
141+
125142
{
126143
Returns the sum of the digits from the given integer, using recursion.
127144
}
128145
function DigitSum(AValue: Int64): Integer;
129146

147+
{
148+
Calculates the sum of all the digits of integer N when epxressed in base Base.
149+
The returned value has the same sign as N.
150+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
151+
exception is raised.
152+
}
153+
function DigitSumBase(N: Int64; const Base: Byte): Integer;
154+
130155
{
131156
Calculates the distance between two given points with double precision
132157
floating point valued coordinates.
@@ -837,6 +862,27 @@ function DigitCount2(const AValue: Int64): Integer;
837862
Result := 1;
838863
end;
839864

865+
{
866+
Returns the number of digits in integer N when expressed in base Base.
867+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
868+
exception is raised.
869+
}
870+
function DigitCountBase(N: Int64; const Base: Byte): Cardinal;
871+
begin
872+
if Base < 2 then
873+
raise SysUtils.EArgumentException.Create(
874+
'Base must be in the range 2..255'
875+
);
876+
if N = 0 then
877+
Exit(1);
878+
N := Abs(N);
879+
Result := 0;
880+
repeat
881+
Inc(Result);
882+
N := N div Base;
883+
until N = 0;
884+
end;
885+
840886
{
841887
Counts the number of digits in the given integer using recursion.
842888
}
@@ -848,6 +894,37 @@ function DigitCountR(AValue: Int64): Integer;
848894
Result := 1 + DigitCountR(AValue div 10)
849895
end;
850896

897+
{
898+
Returns an array containing the digits of integer N when expressed in base
899+
Base. The array is ordered with the least significant digit first.
900+
The returned array contains the decimal value of the digit, for e.g. the hex
901+
symbol F is represented by an array element containing the value 15.
902+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
903+
exception is raised.
904+
}
905+
function DigitsOf(N: Int64; const Base: Byte): SysUtils.TBytes;
906+
var
907+
Idx: Integer;
908+
begin
909+
if Base < 2 then
910+
raise SysUtils.EArgumentException.Create(
911+
'Base must be in the range 2..255'
912+
);
913+
N := Abs(N);
914+
SetLength(Result, DigitCountBase(N, Base));
915+
if N > 0 then
916+
begin
917+
Idx := 0;
918+
repeat
919+
Result[Idx] := N mod Base;
920+
Inc(Idx);
921+
N := N div Base;
922+
until N = 0;
923+
end
924+
else
925+
Result[0] := 0;
926+
end;
927+
851928
{
852929
Returns the sum of the digits from the given integer, using recursion.
853930
}
@@ -859,6 +936,33 @@ function DigitSum(AValue: Int64): Integer;
859936
Result := (AValue mod 10) + DigitSum(AValue div 10)
860937
end;
861938

939+
{
940+
Calculates the sum of all the digits of integer N when epxressed in base Base.
941+
The returned value has the same sign as N.
942+
Bases up to 255 are supported. If Base < 2 then an EArgumentException
943+
exception is raised.
944+
}
945+
function DigitSumBase(N: Int64; const Base: Byte): Integer;
946+
var
947+
SignOfN: Math.TValueSign;
948+
begin
949+
if Base < 2 then
950+
raise SysUtils.EArgumentException.Create(
951+
'Base must be in the range 2..255'
952+
);
953+
if N = 0 then
954+
Exit(0);
955+
SignOfN := Math.Sign(N);
956+
N := Abs(N);
957+
Result := 0;
958+
repeat
959+
Inc(Result, N mod Base);
960+
N := N div Base;
961+
until N = 0;
962+
if SignOfN = Math.NegativeValue then
963+
Result := -1 * Result;
964+
end;
965+
862966
{
863967
Calculates the distance between two given points with double precision
864968
floating point valued coordinates.

0 commit comments

Comments
 (0)