2
var 
  iNum, iNumHun, iNumTens, iNumOnes : Integer;

begin

iNum := StrToInt(edtInput.Text);

iNumHun := iNum DIV 100;

iNumTens := iNum DIV 10;

iNumOnes = iNum DIV 1;
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 Answers2

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.

Screenshot of program in action

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