var
iNum, iNumHun, iNumTens, iNumOnes : Integer;
begin
iNum := StrToInt(edtInput.Text);
iNumHun := iNum DIV 100;
iNumTens := iNum DIV 10;
iNumOnes = iNum DIV 1;
Asked
Active
Viewed 598 times
2

Andreas Rejbrand
- 105,602
- 8
- 282
- 384

Renier
- 21
- 1
-
Obviously this won't work, because e.g 155 DIV 10= 15, so what should I do to make it work? – Renier May 08 '21 at 10:54
-
It's actually probably more efficient to do this using text operations – David Heffernan May 08 '21 at 11:10
-
@DavidHeffernan: Yes, then maybe you can do 20000000 of these per second instead of just 10000000! (Well, no factorial intended.) – Andreas Rejbrand May 08 '21 at 11:14
-
Just use a combination of `MOD` and `DIV`. For example, for hundreds, you can do either `iNumHun := iNum MOD 1000 DIV 100;` or `iNumHun := iNum DIV 100 MOD 10;`. – W. Chang May 09 '21 at 06:36
2 Answers
3
You are very close to a solution. Indeed, you need to iterate and divide the number by 10 on each iteration. The only thing missing is that you need to extract the least significant digit. To do this, you can use the mod
operator:
program Digits;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
var
x, p: Integer;
begin
while True do
begin
Writeln('Enter a non-negative integer:');
Readln(x);
p := 1;
while x <> 0 do
begin
Writeln('position ', p, ': ', x mod 10);
x := x div 10;
Inc(p);
end;
Writeln('---');
end;
end.
Enter a non-negative integer:
155
position 1: 5
position 2: 5
position 3: 1
---
Enter a non-negative integer:
653281205
position 1: 5
position 2: 0
position 3: 2
position 4: 1
position 5: 8
position 6: 2
position 7: 3
position 8: 5
position 9: 6
---

Andreas Rejbrand
- 105,602
- 8
- 282
- 384
-
Why not just use text operations for this? Especially if we start with a decimal representation. Why convert to binary and then back to decimal? – David Heffernan May 08 '21 at 11:11
-
@DavidHeffernan: I don't quite like working with textual representations when I don't have to. Also, in the OP's example, the input is a decimal string, but I bet people will find this SO Q&A from Google and apply it to their (non-textual) integer values. Finally, I find it to be of pedagogical value to point out that the OP is very close to a (in general very decent) solution. – Andreas Rejbrand May 08 '21 at 11:15
-
Also, what if the input is `523 362 102` or `523 362 102`? Safer to actually parse it as an integer. (Try to double-click the 362 in each number.) – Andreas Rejbrand May 08 '21 at 11:18
0
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TSplitNumber=record
type
TDigits = -1..9;
private
data: integer;
function GetDigit(Idx: word): TDigits;
public
property digit[Idx: word] : TDigits read GetDigit;
class operator Implicit(const nr: integer): TSplitNumber;
class operator Implicit(const snr: TSplitNumber): integer;
end;
{ TSplitNumber }
function TSplitNumber.GetDigit(Idx: word): TDigits;
var
Pow :integer;
begin
Result := Low(TDigits);
Pow := round(Power10(10, Idx-2));
// position 0, impossible
// Value -1 or 0, that is the question
if (Idx = 0) or (Pow > ABS(data)) then
Exit;
Result := (data div Pow) mod 10;
Result := ABS(Result);
end;
class operator TSplitNumber.Implicit(const snr: TSplitNumber): integer;
begin
Result := snr.data;
end;
class operator TSplitNumber.Implicit(const nr: integer): TSplitNumber;
begin
Result.data := nr;
end;
var
i: integer;
q: TSplitNumber;
begin
try
i := -123;
q := i;
i := q.digit[0]; //-1
i := q.digit[1]; //3
i := q.digit[2]; //2
i := q.digit[3]; //1
i := q.digit[4]; //-1
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

USauter
- 295
- 1
- 9