Skip to content

Commit 6b31fb0

Browse files
committed
Add tests for DigitPowerSum routine
Added unit test for DigitPowerSum along with methods to test for its exceptions. Regenerated UMathsCatSnippets from CodeSnip to include DigitPowerSum.
1 parent 66e24e3 commit 6b31fb0

File tree

2 files changed

+85
-2
lines changed

2 files changed

+85
-2
lines changed

tests/Cat-Maths/TestUMathsCatSnippets.pas

+31-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ TestMathsCatSnippets = class(TTestCase)
2121
procedure TestDigitSumBase_Except;
2222
procedure TestDigitsOf_ArgExcept;
2323
procedure TestPowNZN_EOverflow;
24+
procedure TestDigitPowerSum_EOverflow;
25+
procedure TestDigitPowerSum_EArgumentException;
2426
function EqualArrays(const Left, Right: TBytes): Boolean;
2527
function ReverseArray(const A: TBytes): TBytes;
2628
published
@@ -52,7 +54,7 @@ TestMathsCatSnippets = class(TTestCase)
5254
procedure TestMaxOfArray_Single;
5355
procedure TestMaxOfArray_Double;
5456
procedure TestMaxOfArray_Extended;
55-
procedure TestPowNZN;
57+
procedure TestPowNZN; // required by DigitPowerSum
5658
procedure TestPowNZZ;
5759
procedure TestPowN;
5860
procedure TestArraySum_Single;
@@ -78,6 +80,7 @@ TestMathsCatSnippets = class(TTestCase)
7880
procedure TestDigitCountBase;
7981
procedure TestDigitSumBase;
8082
procedure TestDigitsOf;
83+
procedure TestDigitPowerSum;
8184
end;
8285

8386
implementation
@@ -417,6 +420,33 @@ procedure TestMathsCatSnippets.TestDigitCountR;
417420
CheckEquals(5, DigitCountR(-12345), 'DigitCountR(-12345)');
418421
end;
419422

423+
procedure TestMathsCatSnippets.TestDigitPowerSum;
424+
begin
425+
CheckEquals(35, DigitPowerSum(135, 10, 2), '#1');
426+
CheckEquals(0, DigitPowerSum(0, 8, 5), '#2');
427+
CheckEquals(3, DigitPowerSum(510, 10, 0), '#3');
428+
CheckEquals(30, DigitPowerSum($FF, 16, 1), '#4');
429+
CheckEquals(12613, DigitPowerSum(1685237180, 10, 4), '#5');
430+
CheckEquals(77907, DigitPowerSum(1685237180 {6472ADBC hex}, 16, 4), '#6');
431+
CheckEquals(6740, DigitPowerSum(1685237180 {14434526674 oct}, 8, 4), '#7');
432+
CheckEquals(-6740, DigitPowerSum(-1685237180 {14434526674 oct}, 8, 4), '#8');
433+
CheckEquals(17, DigitPowerSum(1685237180 {1100100011100101010110110111100 bin}, 2, 4), '#9');
434+
CheckEquals(2409140909625644483, DigitPowerSum(MaxInt {C87E66B7 base 15}, 15, 16), '#10');
435+
CheckException(TestDigitPowerSum_EArgumentException, EArgumentException, 'EArgumentException');
436+
CheckException(TestDigitPowerSum_EOverflow, EOverflow, 'EOverflow');
437+
// EOverflow can also be raised by PowNZN, not tested here
438+
end;
439+
440+
procedure TestMathsCatSnippets.TestDigitPowerSum_EArgumentException;
441+
begin
442+
DigitPowerSum(42, 1, 2); // Base = 1 => EArgumentException
443+
end;
444+
445+
procedure TestMathsCatSnippets.TestDigitPowerSum_EOverflow;
446+
begin
447+
DigitPowerSum(88888888, 10, 20); // overflows High(Int64) by 1
448+
end;
449+
420450
procedure TestMathsCatSnippets.TestDigitsOf;
421451
var
422452
E: TBytes;

tests/Cat-Maths/UMathsCatSnippets.pas

+54-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 : Wed, 08 Jan 2025 17:47:45 GMT.
9+
* Generated on : Thu, 09 Jan 2025 10:55:06 GMT.
1010
* Generated by : DelphiDabbler CodeSnip Release 4.24.0.
1111
*
1212
* The latest version of CodeSnip is available from the CodeSnip GitHub project
@@ -129,6 +129,18 @@ function DigitCountBase(N: Int64; const Base: Byte): Cardinal;
129129
}
130130
function DigitCountR(AValue: Int64): Integer;
131131

132+
{
133+
Calculates the sum of all the digits of integer N in base Base where each
134+
digit is raised to the power Exponent. The returned value has the same sign as
135+
N.
136+
If the result is too large to be represented as an Int64 value then an
137+
EOverflow exception is raised.
138+
Bases up to 255 are supported. If Base <= 2 then an EArgumentException
139+
exception is raised.
140+
}
141+
function DigitPowerSum(N: Integer; const Base: Byte; const Exponent: Byte):
142+
Int64;
143+
132144
{
133145
Returns an array containing the digits of integer N when expressed in base
134146
Base. The array is ordered with the least significant digit first.
@@ -358,6 +370,8 @@ function PowN(const X: Extended; const N: Integer): Extended;
358370

359371
{
360372
Raises integer X to non-negative integer power N.
373+
If the result is too large to be represented as an Int64 value then an
374+
EOverflow exception is raised.
361375
}
362376
function PowNZN(const X: Integer; const N: Cardinal): Int64;
363377

@@ -894,6 +908,43 @@ function DigitCountR(AValue: Int64): Integer;
894908
Result := 1 + DigitCountR(AValue div 10)
895909
end;
896910

911+
{
912+
Calculates the sum of all the digits of integer N in base Base where each
913+
digit is raised to the power Exponent. The returned value has the same sign as
914+
N.
915+
If the result is too large to be represented as an Int64 value then an
916+
EOverflow exception is raised.
917+
Bases up to 255 are supported. If Base <= 2 then an EArgumentException
918+
exception is raised.
919+
}
920+
function DigitPowerSum(N: Integer; const Base: Byte; const Exponent: Byte):
921+
Int64;
922+
var
923+
SignOfN: Math.TValueSign;
924+
Digit: Integer;
925+
PowerDigit: Int64;
926+
begin
927+
if Base < 2 then
928+
raise SysUtils.EArgumentException.Create(
929+
'Base must be in the range 2..255'
930+
);
931+
if N = 0 then
932+
Exit(0);
933+
SignOfN := Math.Sign(N);
934+
N := Abs(N);
935+
Result := 0;
936+
repeat
937+
Digit := N mod Base;
938+
PowerDigit := PowNZN(Digit, Exponent);
939+
if High(Int64) - PowerDigit < Abs(Result) then
940+
raise SysUtils.EOverflow.Create('Overflow calculating digit power sum');
941+
Result := Result + PowerDigit;
942+
N := N div Base;
943+
until N = 0;
944+
if SignOfN = Math.NegativeValue then
945+
Result := -1 * Result;
946+
end;
947+
897948
{
898949
Returns an array containing the digits of integer N when expressed in base
899950
Base. The array is ordered with the least significant digit first.
@@ -1610,6 +1661,8 @@ function PowN(const X: Extended; const N: Integer): Extended;
16101661

16111662
{
16121663
Raises integer X to non-negative integer power N.
1664+
If the result is too large to be represented as an Int64 value then an
1665+
EOverflow exception is raised.
16131666
}
16141667
function PowNZN(const X: Integer; const N: Cardinal): Int64;
16151668
var

0 commit comments

Comments
 (0)