New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add versions of DigitCount
& DigitSum
that work for all bases
#17
Comments
function DigitCountBase(X: Int64; Base: Byte): Cardinal:
begin
Assert(Base > 1);
if X <> 0 then
Result := Math.Floor(Math.LogN(Base, Abs(X))) + 1
else
Result := 1;
end; |
DigitCount
that works for all basesDigitCount
& DigitSum
that work for all bases
DigitSumBase Source: Wikipedia |
function DigitSumBase(X: Int64; Base: Byte): Integer;
begin
Assert(Base > 1);
if X = 0 then
Exit(0);
var SignOfX := Math.Sign(X);
X := Abs(X);
var K := Math.Floor(Math.LogN(X));
Result := 0;
for var I := 0 to K do
begin
var BToPowerI := PowNZN9(Base, I);
var BToPowerIPlusOne := PowNZN9(Base, I + 1);
var D := ((X mod BToPowerIPlusOne) - (X mod BToPowerI)) div BToPowerI;
Result := Result + D;
end;
if SignOfX < 0 then
Result : -1 * Result;
end; |
function DigitArray(N: UInt64; Base: TByte): TArray<Byte>;
begin
Assert(Base > 1);
SetLength(Result, DigitCountBase(N, Base));
if N > 0 then
for I := 0 to High(Result) do
begin
var BToPowerI := PowNZN9(Base, I);
var BToPowerIPlusOne := PowNZN9(Base, I + 1);
var Result[I] := ((X mod BToPowerIPlusOne) - (X mod BToPowerI)) div BToPowerI;
end
else
Result[0] := 0;
end; |
Alternative function DigitSumBase(X: Int64; Base: Byte): Integer;
begin
Assert(Base > 1);
if X = 0 then
Exit(0);
var SignOfX := Math.Sign(X);
X := Abs(X);
var K := Math.Floor(Math.LogN(X));
Result := 0;
var BToPowerI := 1; // B to power I when I = 0
for var I := 0 to K do
begin
var BToPowerIPlus1 := Base * BToPowerI;
var D := ((X mod BToPowerIPlus1) - (X mod BToPowerI)) div BToPowerI;
Result := Result + D;
BToPowerI := BToPowerIPlus1;
end;
if SignOfX < 0 then
Result : -1 * Result;
end; |
Alternative function DigitArray(N: UInt64; Base: TByte): TArray<Byte>;
begin
Assert(Base > 1);
SetLength(Result, DigitCountBase(N, Base));
if N > 0 then
begin
var BToPowerI := 1; // B to power I when I = 0
for I := 0 to High(Result) do
begin
var BToPowerIPlus1 := Base * BToPowerI;
Result[I] := ((X mod BToPowerIPlus1) - (X mod BToPowerI)) div BToPowerI;
BToPowerI := BToPowerIPlus1;
end;
end
else
Result[0] := 0;
end; |
Can have overloads of all above functions for UInt64 parameter that are same except don't need to worry about sign. In fact the above functions could be rewritten to handle sign then call unsigned overload. E.g.: function DigitSumBase(const X: UInt64; const Base: Byte): Cardinal; overload;
begin
Assert(Base > 1);
if X = 0 then
Exit(0);
var K := Math.Floor(Math.LogN(X)); // digit count - 1
Result := 0;
var BToPowerI := 1; // B to power I when I = 0
for var I := 0 to K do
begin
var BToPowerIPlus1 := Base * BToPowerI;
var D := ((X mod BToPowerIPlus1) - (X mod BToPowerI)) div BToPowerI;
Result := Result + D;
BToPowerI := BToPowerIPlus1;
end;
end; function DigitSumBase(X: Int64; Base: Byte): Integer; overload;
begin
Assert(Base > 1);
// safe to convert Cardinal to Integer since max possible Result is much lower than MaxInt
Result := Integer(DigitSumBase(UInt64(Abs(X)), Base));
if X < 0 then
Result : -1 * Result;
end; |
Version of function DigitPowerSum(X: UInt64; Base: Byte; Exponent: Cardinal): Cardinal;
begin
Assert(Base > 1);
if X = 0 then
Exit(0);
var K := Math.Floor(Math.LogN(X)); // digit count - 1
Result := 0;
var BToPowerI := 1; // B to power I when I = 0
for var I := 0 to K do
begin
var BToPowerIPlus1 := Base * BToPowerI;
var D := ((X mod BToPowerIPlus1) - (X mod BToPowerI)) div BToPowerI;
Result := Result + PowNZN(D, Exponent);
BToPowerI := BToPowerIPlus1;
end;
end; function DigitPowerSum(X: Int64; Base: Byte; Exponent: Cardinal): Integer; overload;
begin
Assert(Base > 1);
var UResult :≈ DigitSumBase(UInt64(Abs(X)), Base, Exponent);
if UResult > MaxInt then
raise EOutOfRange('DigitPowerSum: Result exceeds MaxInt');
Result := Integer(UResult);
if X < 0 then
Result : -1 * Result;
end; |
If n ∈ ℕ (n ≠ 0) and b is the number base (b>1) then the number of digits, d, of n is
The text was updated successfully, but these errors were encountered: