Recent

Author Topic: Convert a number from X base to decimal without array/string  (Read 10772 times)

Olimak

  • New member
  • *
  • Posts: 8
Convert a number from X base to decimal without array/string
« on: September 11, 2017, 04:39:46 am »
Hello everyone. I'm working on a project but I've gotten stuck. First off I'm working in FreePascal (ver 2.6.4). I need to make a program capable of converting a number of any base 2 to 16 to decimal. My problem however is that I can't use things like array/string/readkey/type, etc. Basically I can only use the functions repeat/while/for/if/case/read(ln)/write(ln). As for types, only integer/real/boolean/char.. My problem arises from how I need to input the variable. It needs to be:

>base:number.
>answer in base 10

For example

>16:123.
>291

Note how the entire number is written in one line, and how "base" and "number" are separated by a ":". I can't really get that to work.

Another thing is my use of Horner's Rule, which is:

result = 1stNumber + (result*base)  - in this case result = 0 since there was no prior input.
result = 2ndNumber + (result*base)
result = 3rdNumber + (result*base)
...etc

Replacing the numbers with "123":

result = 1
result = 2 + (1*16)
result = 3 + (18*16)
result = 291

But I can't seem to separate the input to do so, least not without array. I know I should technically be able to read the input numbers and analyze them one by one, converting them from char to integer by using Ord, but I'm not sure how to do it.

I'm rather new at this so any help is highly appreciated.
« Last Edit: September 11, 2017, 05:35:11 am by Olimak »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Convert a number from X base to decimal without array/string
« Reply #1 on: September 11, 2017, 04:57:44 am »
If you handle the input as string (readln) then you can use function pos to locate the colon. A copy will be able to do the rest.

But you could just as well parse the string manually, using val for instance to convert.

What is it with these assignments with ridiculous restrictions ?

Quote
I can only use functions like repeat/while/for/if/case, etc.

PS: what does etc. mean ? That you are allowed to use classes, objects and interfaces ?

The quoted names are reserved words btw.
« Last Edit: September 11, 2017, 05:06:43 am by molly »

Olimak

  • New member
  • *
  • Posts: 8
Re: Convert a number from X base to decimal without array/string
« Reply #2 on: September 11, 2017, 05:10:15 am »
I realized that I didn't specify which ones I could use so I edited the post. Can't use the ones you recommended sadly.
As for the restrictions, the other functions haven't been taught. I only know of them since I researched them on my own.

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #3 on: September 11, 2017, 05:17:01 am »
I nutted this out, then you clarified your post and molly contributed.

YOU CANNOT DO IT WITHOUT STRINGS, BECAUSE IT IS A STRING TO START WITH.

here is code, just add the necessary bits:

Code: Pascal  [Select][+][-]
  1.  var I,P,Base,BaseNumber,Multi,DecNum:longint; BaseStr:string;
  2.  
  3.   P:=pos(':',InputStr); // 16:123
  4.   Base:=strtoint(copy(InputStr,1,P-1)); // = 16
  5.   BaseNumber:=strtoint(copy(InputStr,P+1,255)); // = 123
  6.   BaseStr:=inttostr(BaseNumber); // ="123" or just use the previous copy.
  7.   Multi:=1;
  8.   DecNum:=0;
  9.   For I:=length(BaseStr) downto 1 do begin
  10.      DecNum:=DecNum+Multi*strtoint(BaseStr[I]);
  11.      Multi:=Multi*Base;
  12.   end;
  13.   writeln(DecNum);

As molly said

Quote
ridiculous restrictions

B
Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Convert a number from X base to decimal without array/string
« Reply #4 on: September 11, 2017, 05:28:02 am »
YOU CANNOT DO IT WITHOUT STRINGS, BECAUSE IT IS A STRING TO START WITH.
yes, we can  :) (see below)

Quote
ridiculous restrictions

I understand that when learning there ought to be some sort of restriction (otherwise students could go fetch a ready to go unit from some-one else) but sometimes it is painful because it has nothing to do with solving the assignment.

The only thing i can think of for restriction of strings would be that you could abuse them as an array ;-)

Code: Pascal  [Select][+][-]
  1. function ReadLineFromInput: string;
  2. var
  3.   ti: text;
  4.   C: char;
  5. begin
  6.   Result := '';
  7.  
  8.   ti := System.Input;
  9.   While not eoln(ti) do
  10.   begin
  11.     Read(ti, c);
  12.     Result := Result + C;
  13.   end;
  14. end;
  15.  
  16.  
  17. begin
  18.   WriteLn('ReadLineFromInputInput returned : "', ReadLineFromInput, '"');
  19. end.
  20.  

I take it that TS is educated enough to see through the use of string. it was only meant to show that it is possible to do. No idea how that behaves on a unicode enabled shell though. On the other hand.... the restrictions are from the dark ages, so am assuming ms-dos  :)

PS: if you are also not allowed to use eoln then i'm afraid you're doomed. modern windows does not seem to fetch chars with read without space separator.
« Last Edit: September 11, 2017, 05:30:52 am by molly »

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #5 on: September 11, 2017, 05:34:32 am »
But molly, your output is a string.

Quote
: string;

text is a string;

And a character is a single byte string.

Strings everywhere !!

B
Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Convert a number from X base to decimal without array/string
« Reply #6 on: September 11, 2017, 05:48:29 am »
LOL...

But molly, your output is a string.
I covered that in my answer, with an indication nonetheless  :)

Quote
text is a string;
Please file a bug-report that official documentation is wrong.

Quote
And a character is a single byte string.
Please file a bug-report that official documentation is wrong.

Quote
Strings everywhere !!
yes, even the source-code is all strings :D

just for the record, don't file those reports... just telling you that not all is string... unless you meant the source-code that implements/defines them ;-)

Olimak

  • New member
  • *
  • Posts: 8
Re: Convert a number from X base to decimal without array/string
« Reply #7 on: September 11, 2017, 05:54:18 am »
We haven't learned "function" yet, so I'm sure we can't use it. Again, we're not allowed to use "string".
As for "text", we haven't worked with it. Though I don't think there'd be a problem.

Right now what I'm trying to do is have the input be read one by one and printed until completion with a "for". Any ideas?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Convert a number from X base to decimal without array/string
« Reply #8 on: September 11, 2017, 06:01:34 am »
*sigh*

it was an example. strip away the function declaration, remove the string, make sure all resides as main entry code and you have your loop.

Code: Pascal  [Select][+][-]
  1. var
  2.   ti: text;
  3.   c: char;
  4. begin
  5.   ti := System.Input;
  6.  
  7.   While not eoln(ti) do
  8.   begin
  9.     Read(ti, c);
  10.     Write(c);
  11.   end;
  12. end.
  13.  

Your job: how to store a bunch of characters (until colon was read) into a integer variable as a number. Same for the characters after the colon.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Convert a number from X base to decimal without array/string
« Reply #9 on: September 11, 2017, 06:09:14 am »
this pseudo code should get you started
Code: Pascal  [Select][+][-]
  1. program Test;
  2. uses crt;
  3. const
  4.   stBase = 0;
  5.   stNumber = 1;
  6.   kExit = 27;
  7.   kbaseExit = ':';
  8.   kNumExit = #13;
  9.  
  10. var
  11.   vReader : Char;
  12.   vNumber : integer;
  13.   vState  : integer;
  14.   vBase   : integer;
  15.  
  16. procedure ResetInput;
  17. begin
  18.    vReader := #0;
  19.    vInput := 0;
  20.    vState := stBase;
  21. end;
  22.  
  23. procedure ChangeState(NewState:Byte);
  24. begin
  25.   vState := NewState;
  26. end;
  27.  
  28. function ReadNextDigit:Char;
  29. begin
  30.   Result := ReadKey;
  31. end;
  32.  
  33. function DigitToNo(const aDigit:Char):Integer;
  34. begin
  35.   if aDigit in ['0'..'9'] then result := ord(aDigit) - ord(0)
  36.   else if aDigit in ['A'..'Z']  then result := 10 + ord(aDigit) - ord('A');
  37.   //add more sets as needed.
  38. end;
  39.  
  40. function CharInBase(const aChar:Char; aBase:Byte):boolean;
  41. begin
  42.   case aBase of
  43.     2  : Result := aChar in ['0'..'1'];
  44.     8  : Result := aChar in ['0'..'7'];
  45.     16 : Result := aChar in ['0'..'9','A'..'F'];
  46.   else
  47.     Result := False;
  48.   end;
  49. end;
  50.  
  51. begin
  52.    ResetInput;
  53.    Write('Enter a Number :');
  54.    repeat
  55.     //Start with the base
  56.      vReader := ReadNextDigit;
  57.      case vReader of
  58.        '0'..'9','A'..'Z' : begin
  59.            Write(vReader);
  60.            case vState of
  61.              stBase   : vBase := (vBase * 10) + DigitToNo(vReader);
  62.              stNumber : begin
  63.                           if vBase <> 0 then begin
  64.                             if CharInBase(vReader, vBase) then
  65.                               vNumber := vNumber * vBase + DigitToNo(vReader)
  66.                             else Beep;
  67.                           end else Beep;
  68.                         end;
  69.            end;
  70.          end;
  71.        ':' : if vState = stBase then ChangeState(stNumber) else Beep; // If I remember correctly in dos days beep was #7, I'm not sure though.
  72.        #10 : vReader := ReadNextDigit;
  73.        #13 : begin
  74.                WriteLn('You entered : ', vNumber);
  75.                ResetInput;
  76.                WriteLn();
  77.                Write('Enter a Number :');
  78.              end;
  79.        #0..#9, #11, #12, #14..#31 : vReader:= ReadNextDigit; //ignore control characters.
  80.      else
  81.          Beep;
  82.      end;
  83.    until vReader = #27;//pressing esc will exit the program.
  84. end.
  85.  
Keep in mind everything was typed in the browser, no compile no IDE so it has a number of problems but the general idea is there, make it work.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #10 on: September 11, 2017, 06:17:10 am »
welcome taazz,

I was improving molly's ...

Code: Pascal  [Select][+][-]
  1. var
  2.   ti: text;
  3.   c: char;
  4.   FirstNumber,SecondNumber,WingNumber,Multi:longint;
  5. begin
  6.   ti := System.Input;
  7.   Multi:=1;
  8.   FirstNumber:=0;
  9.   SecondNumber:=0;
  10.   WingNumber:=0;
  11.   While not eoln(ti) do
  12.   begin
  13.     Read(ti, c);
  14.     if c=':' then
  15.       begin
  16.         FirstNumber:=WingNumber;
  17.         Multi:=1;
  18.         WingNumber:=0;
  19.       end
  20.     else
  21.       begin
  22.         WingNumber:=WingNumber+(ord(c)-48)*Multi;    
  23.         Multi:=Multi*10;
  24.       end;  
  25.     Write(c);
  26.   end;
  27.   SecondNumber:=WingNumber;
  28.   writeln;
  29.   writeln;
  30.   writeln(FirstNumber,':',SecondNumber); // 16:123
  31.   writeln('Devised by molly & Bazzao. So there.');
  32.  // then do the calculation as devised by ...
  33. end.

B
« Last Edit: September 11, 2017, 06:19:07 am by Bazzao »
Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #11 on: September 11, 2017, 06:28:40 am »
OOps. Mine just crashed. I was thinking in reverse string order.

the fix is

Multiply WingNumber by 10 before adding current C.

so Multi is not used.
I'll rewrite the code.

Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #12 on: September 11, 2017, 06:31:26 am »
Previous fixed:

Code: Pascal  [Select][+][-]
  1. var
  2.   ti: text;
  3.   c: char;
  4.   FirstNumber,SecondNumber,WingNumber:longint;
  5. begin
  6.   ti := System.Input;
  7.   FirstNumber:=0;
  8.   SecondNumber:=0;
  9.   WingNumber:=0;
  10.   While not eoln(ti) do
  11.   begin
  12.     Read(ti, c);
  13.     if C=':' then
  14.       begin
  15.         FirstNumber:=WingNumber;
  16.         WingNumber:=0;
  17.       end
  18.     else
  19.       begin
  20.         WingNumber:=WingNumber*10+(ord(C)-48);    
  21.       end;  
  22.     Write(c);
  23.   end;
  24.   SecondNumber:=WingNumber;
  25.   writeln;
  26.   writeln;
  27.   writeln(FirstNumber,':',SecondNumber);
  28.   writeln('Devised by molly & Bazzao. So there.');
  29. end.
  30.  

B
Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Convert a number from X base to decimal without array/string
« Reply #13 on: September 11, 2017, 06:39:46 am »
what would you want more   :)

Some copy-paste from Bazzao's code combined with taazz' smart approaches, then strip/rewrite as indicated by provided restrictions and you're done.

I've never done any of my homework assignments that quickly :D

Bazzao

  • Full Member
  • ***
  • Posts: 178
  • Pies are squared.
Re: Convert a number from X base to decimal without array/string
« Reply #14 on: September 11, 2017, 01:43:51 pm »
Olimak,

I've done the homework for you.

Enjoy:  :-[

Code: Pascal  [Select][+][-]
  1. program XbaseToDec1;
  2.  
  3. uses crt;
  4.  
  5. {$R *.res}
  6.  
  7. var
  8.   AllYourBase,
  9.   TheBigResultNumber,
  10.   WingCommanderNumber     :longint;
  11.   MainScreenTurnOn,
  12.   GoWalkAbout             :boolean;
  13.  
  14. procedure WeGetSignal;
  15. var
  16.   C:char;
  17. begin
  18.   clrscr;
  19.   writeln('We get signal ... (enter your calc, if you dare) ...');
  20.   writeln;
  21.   AllYourBase:=0;
  22.   TheBigResultNumber:=0;
  23.   WingCommanderNumber:=0;
  24.   MainScreenTurnOn:=false;
  25.   repeat
  26.     C:=Readkey;
  27.     if (C=':') and not MainScreenTurnOn then
  28.       begin
  29.         Write(C);
  30.         AllYourBase:=WingCommanderNumber;
  31.         WingCommanderNumber:=0;
  32.         TheBigResultNumber:=0;
  33.         MainScreenTurnOn:=true;
  34.       end
  35.     else if C in ['0'..'9'] then
  36.       begin
  37.         Write(C);
  38.         WingCommanderNumber:=WingCommanderNumber*10+(ord(C)-48);
  39.         if MainScreenTurnOn then
  40.           TheBigResultNumber:=TheBigResultNumber*AllYourBase+(ord(C)-48)
  41.       end
  42.     else if C in ['Q','q',#27] then
  43.       Halt;
  44.   until (C=#13) or (C='=');
  45.   writeln;
  46.   writeln;
  47.   writeln('Main screen turn on ...');
  48.   writeln(AllYourBase,':',WingCommanderNumber);
  49.   writeln('Result = ',TheBigResultNumber);
  50.   writeln;
  51.   writeln('All your base are belong to us!');
  52.   writeln;
  53.   writeln('https://www.youtube.com/watch?v=jQE66WA2s-A');
  54.   writeln;
  55.   writeln;
  56.   writeln;
  57.   write('Press q/Q/esc to go Walkabout C:\>');
  58.   C:=Readkey;
  59.   if C in ['Q','q',#27] then
  60.     GoWalkAbout:=true;
  61. end;
  62.  
  63. Begin
  64.   GoWalkAbout:=false;
  65.   while GoWalkAbout=false do
  66.     WeGetSignal;
  67. End.
  68.  

You will have to replace readkey with something else, so it fits inside the scope. 

 :D :D :D :D :D :D :D :D :D :D :D :D

B
Bazza

Lazarus 2.0.10; FPC 3.2.0; SVN Revision 63526; x86_64-win64-win32/win64
Windows 10.

 

TinyPortal © 2005-2018