Jump to content
Emmerisch

Can anyone spot the errors?

Recommended Posts

Hello, 

I was making a program for school and I saw three error messages that I couldn't easily fix. These 3 are as a Screenshot in the Attachment. Can anyone tell me how I can fix this error´s. I also need to say that I only have Delphie 6 Profesionale and no later Version.

To the Program: 

The program should be able to convert numbers under the number systems: decimal, binary and hexadecimal.

Here is the program code:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Math, Buttons;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Edit1: TEdit;
    BitBtn1: TBitBtn;
    Label5: TLabel;
    BitBtn2: TBitBtn;
    Label6: TLabel;
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    function DecimalToBinary(decimal: Integer): string;
  end;

var
  Form1: TForm1;
  iSelect: Integer;

implementation

{$R *.dfm}

function TForm1.DecimalToBinary(decimal: Integer): string;
var
  remainder: Integer;
begin
  Result := '';
  while decimal > 0 do
  begin
    remainder := decimal mod 2;
    Result := IntToStr(remainder) + Result;
    decimal := decimal div 2;
  end;
end;
function BinaryToDecimal(binary: string): Integer;
var
  i, power, digit: Integer;
begin
  Result := 0;
  power := Length(binary) - 1;
  for i := 1 to Length(binary) do
  begin
    digit := StrToInt(binary[i]);
    Result := Result + (digit * Trunc(Power(2, power)));
    Dec(power);
  end;
end;

function DecimalToHexadecimal(decimal: Integer): string;
const
  hexDigits: array[0..15] of Char = '0123456789ABCDEF';
var
  remainder: Integer;
begin
  Result := '';
  while decimal > 0 do
  begin
    remainder := decimal mod 16;
    Result := hexDigits[remainder] + Result;
    decimal := decimal div 16;
  end;
end;

function HexadecimalToDecimal(hexadecimal: string): Integer;
var
  i, power, digit: Integer;
begin
  Result := 0;
  power := Length(hexadecimal) - 1;
  for i := 1 to Length(hexadecimal) do
  begin
    if hexadecimal[i] in ['0'..'9'] then
      digit := Ord(hexadecimal[i]) - Ord('0')
    else
      digit := Ord(hexadecimal[i]) - Ord('A') + 10;
    Result := Result + (digit * Trunc(Power(16, power)));
    Dec(power);
  end;
end;

function HexadecimalToBinary(hexadecimal: string): string;
const
  hexToBinary: array['0'..'F'] of string =
    ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',
     '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');
var
  i: Integer;
begin
  Result := '';
  for i := 1 to Length(hexadecimal) do
    Result := Result + hexToBinary[hexadecimal[i]];
end;

function BinaryToHexadecimal(binary: string): string;
const
  binaryToHex: array['0000'..'1111'] of Char =
    ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
  i: Integer;
  paddedBinary: string;
begin
  Result := '';
  paddedBinary := binary;
  while Length(paddedBinary) mod 4 <> 0 do
    paddedBinary := '0' + paddedBinary;
  for i := 1 to Length(paddedBinary) div 4 do
    Result := Result + binaryToHex[Copy(paddedBinary, (i - 1) * 4 + 1, 4)];
end;


procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  iSelect := ComboBox1.ItemIndex;
  Label4.Caption := Edit1.Text;
  if iSelect = 0 then
  begin
    Label6.Caption := 'dez ---> bin';
    Label1.Caption := DecimalToBinary(StrToInt(Edit1.Text));
  end;
  if iSelect = 1 then
  begin
    Label6.Caption := 'dez ---> hex';
    Label1.Caption := DecimalToHexadecimal(StrToInt(Edit1.Text));
  end;
  if iSelect = 2 then
  begin
    Label6.Caption := 'bin ---> dez';
    Label1.Caption := BinaryToDecimal(StrToInt(Edit1.Text));
  end;
  if iSelect = 3 then
  begin
    Label6.Caption := 'bin ---> hex';
    Label1.Caption := BinaryToHexadecimal(StrToInt(Edit1.Text));
  end;
  if iSelect = 4 then
  begin
    Label6.Caption := 'hex ---> dez';
    Label1.Caption := HexadecimalToDecimal(StrToInt(Edit1.Text));
  end;
  if iSelect = 5 then
  begin
    Label6.Caption := 'hex ---> bin';
    Label1.Caption := HexadecimalToBinary(StrToInt(Edit1.Text));
  end;
end;

end.

I know the Errors are written in German.

Here are the Errors in English:

[Error] Unit2.pas(58): Missing operator or semicolon
[Error] Unit2.pas(90): Missing operator or semicolon
[Error] Unit2.pas(99): Number of elements is different from declaration

 

bye.

delphie_errors.png

Edited by Emmerisch

Share this post


Link to post

You cannot use the built-in function Power, when there is a local variable with the same name. Note, that Delphi/Pascal is case insensitive.

  • Like 1

Share this post


Link to post

Ahh, the joy of learning to sniff out syntax errors ...

 

Line numbers on the code would make this easier for people here to look at, but there are a few lines of code that look really fishy to me.

 

One thing is to ask yourself what these two declarations REALLY mean -- they do NOT mean what you think.

 

hexToBinary: array['0'..'F'] of string =

Here's an ASCII table. Count up how many characters are between '0' and 'F'

 

https://www.ascii-code.com

 

And I have no idea how the compiler might be treating this if it's not raising any sort of warnings or errors...

binaryToHex: array['0000'..'1111'] of Char =
  • Thanks 1

Share this post


Link to post

Thanks for the help, I've now changed the power variable to power1 and the first two error messages have gone. Now the third and 2 new are there, which apparently really is from the code:

hexToBinary: array['0'..'F'] of string =
    ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',
     '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');

and:

binaryToHex: array['0000'..'1111'] of Char =
    ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');

The Errors are:

[Error] Unit2.pas(99): Number of elements is different from declaration

[Error] Unit2.pas(110): Incompatible types: 'Integer' and 'String'

[Error] Unit2.pas(111): Number of elements is different from declaration

Line 99 is:     '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');

Line 110 is:   binaryToHex: array['0000'..'1111'] of Char =

Line 111 is:  ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');

 

I don't know why Delphi thinks this is a problem because 0-F equals 0000-1111 digits. Both are 16, i.e.: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' = 16 numbers and '0000', '0001','0010', '0011', '0100', '0101','0110' , '0111',
'1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111'=16 numbers. I just don't see anything wrong in that.

Edited by Emmerisch

Share this post


Link to post

@Emmerisch

 

you can try this way...

type
  TMyDic = record
    FChar: char;
    FBinStr: string; // [4];
  end;

  TArrMyDic = array [0 .. 15] of TMyDic;

const
  MyDic: TArrMyDic = (             { }
    (FChar: '0'; FBinStr: '0000'), { }
    (FChar: '1'; FBinStr: '0001'), { }
    (FChar: '2'; FBinStr: '0010'), { }
    (FChar: '3'; FBinStr: '0011'), { }
    (FChar: '4'; FBinStr: '0100'), { }
    (FChar: '5'; FBinStr: '0101'), { }
    (FChar: '6'; FBinStr: '0110'), { }
    (FChar: '7'; FBinStr: '0111'), { }
    (FChar: '8'; FBinStr: '1000'), { }
    (FChar: '9'; FBinStr: '1001'), { }
    (FChar: 'A'; FBinStr: '1010'), { }
    (FChar: 'B'; FBinStr: '1011'), { }
    (FChar: 'C'; FBinStr: '1100'), { }
    (FChar: 'D'; FBinStr: '1101'), { }
    (FChar: 'E'; FBinStr: '1110'), { }
    (FChar: 'F'; FBinStr: '1111')  { }
    );

function MyFindBin(AMyDic: TArrMyDic; AChar: char): string;
begin
  result := '';
  //
  for var C in AMyDic do
    if (C.FChar = AChar) then
      exit(C.FBinStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LHexToBin: string;
  LResult  : string;
  i        : integer;
begin
  LHexToBin := 'F0D138A2';
  //
  { for var C in LHexToBin do
    LResult := LResult + '-' + MyFindBin(MyDic, C);
    //
    Memo1.Text := LResult; }
  //
  LResult := '';
  for i   := 1 to length(LHexToBin) - 1 do
    begin
      LResult := LResult + '-' + MyFindBin(MyDic, LHexToBin[i]);
    end;
  //
  Memo1.Text := LResult;
end;

 

Edited by programmerdelphi2k

Share this post


Link to post

or this way...

type
  TMyChars = array [0 .. 15] of char;
  TMyBins  = array [0 .. 15] of string;

const
  MyChars: TMyChars = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
  MyBins: TMyBins   = ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');

function MyFindIt(AMyChars: TMyChars; AChar: char): integer;
begin
  result := -1;
  //
  for var i: integer := 0 to high(AMyChars) do
    if AMyChars[i] = AChar then
      exit(i);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LHexToBin: string;
  LResult  : string;
  x        : integer;
begin
  LHexToBin := Trim('  F0D138A2zzz   ');
  //
  for var i: integer := 1 to Length(LHexToBin) do
    begin
      x := MyFindIt(MyChars, LHexToBin[i]);
      //
      if (x > -1) then
        Memo1.Lines.Add(MyBins[x]);
    end;
end;

 

Share this post


Link to post

or that way

const
  MyBins3: string = '0,00001,00012,00103,00114,01005,01016,01107,01118,10009,1001A,1010B,1011C,1100D,1101E,1110F,1111';

function MyFindIt2(AMyChars: string; AChar: char): string;
var
  i: integer;
begin
  result := '';
  //
  i := Pos((AChar + ','), AMyChars, 1);
  //
  if (i > 0) then
    result := Copy(MyBins3, i + 2, 4);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  LHexToBin: string;
begin
  LHexToBin := Trim('  F0D138A2zzz   ');
  //
  for var i: integer := 1 to Length(LHexToBin) do
    Memo1.Lines.Add(MyFindIt2(MyBins3, LHexToBin[i]));
end;

 

Share this post


Link to post
3 hours ago, Emmerisch said:

binaryToHex: array['0000'..'1111'] of Char =

is not a "ordinal" ...  array['0'.. '9']  of Char is valid!

Share this post


Link to post
15 hours ago, programmerdelphi2k said:

is not a "ordinal" ...  array['0'.. '9']  of Char is valid!

Char can be used as an index, but string cannot. Don't be confused by the fact that the syntax for declaring char and string literals is the same.

Share this post


Link to post
1 hour ago, PeterBelow said:

string literals is the same.

and Chars is not a "Ordinals"?

Edited by programmerdelphi2k

Share this post


Link to post
22 hours ago, programmerdelphi2k said:

and Chars is not a "Ordinals"?

Char (singular) is an ordinal type and can thus be used as index for an array but a string is not an ordinal type. The compiler will convert a single char to a string if required, e.g. if you assign a value/variable of type char to one of type string, but not vice versa. Even a string consisting of only a single character cannot be assigned directly to a variable of type char.

  • Like 3

Share this post


Link to post
1 hour ago, PeterBelow said:

Char (singular) is an ordinal type and can thus be used as index for an array but a string is not an ordinal type. The compiler will convert a single char to a string if required, e.g. if you assign a value/variable of type char to one of type string, but not vice versa. Even a string consisting of only a single character cannot be assigned directly to a variable of type char.

I think you are stretching this subject unnecessarily!
What I stated in my post above, was that "0".."9" is valid because it is an ordinal type.... and "0000"..."1111" IS NOT! Because, THERE IS NO way to know what would be the "NEXT VALUE" in a "NON ORDINAL" universe (WITHOUT NATURAL ORDER)

I hope it ends here, because I will not continue the discussion!

 

On 5/13/2023 at 4:45 PM, programmerdelphi2k said:
On 5/13/2023 at 1:18 PM, Emmerisch said:

binaryToHex: array['0000'..'1111'] of Char =

is not a "ordinal" ...  array['0'.. '9']  of Char is valid!

 

Share this post


Link to post
On 5/14/2023 at 1:59 PM, programmerdelphi2k said:

and Chars is not a "Ordinals"?

I don't really understand this either. I think @PeterBelow was just stating this clearly, and did a good job of it. 

  • Sad 1

Share this post


Link to post

Consider that the ordinal value of any specific character is given by the position of the character in the ASCII table, which is why I posted a link to it. Seems the OP didn't even notice it. Instead, we ended up with a senseless debate about ordinal values of characters versus strings. smh.

 

According to the ASCII table, the ordinal (decimal) value of the character '0' (zero) is given as: Ord('0') = 48.

 

You can see this if you display the result of: Format( 'Ord(''0'') = %d', [Ord('0')] ); since Ord() returns an integer value, and this displays it as a decimal number.

 

The ordinal value of the character '9' is: Ord('9') = 57.

 

However, while the next Hex digit is 'A' (or 'a'), the character following '9' is Chr(58) which = ':' (colon).

 

In practice, Hex digits are not case sensitive, so the hex value of 'a' is the same as the hex value of 'A', both of which correspond to the decimal value of 10 (ten).

 

However, Ord('A') = 65 while Ord('a') = 97.

 

Ord('9') is 57 while Ord('A') = 65. So the ordinal values of the 16 ASCII characters that are used to represent Hex digits is not a continuous array of 16 values from:

 

it goes from Ord('0') = 48 to Ord('F') = 70.

 

The range between those two ends is 22, not 16.

 

And if you use lower-case 'a'..'f' then the difference is Ord('a') - Ord('A'), or the entire range defined as [48 .. 102], again far more than 16 elements.

 

The ordinal value of a string is undefined. So Ord( '0000' ) is an error, neither zero nor 48. Never mind that these are actually BINARY representations (0 or 1), and to the compiler they're just 4-character strings.

 

You have to parse the digits in each position of a Hex number the same way as you do decimal numbers, except you need to multiply each successive position by a power of 16 rather than 10.

 

Simple arrays that serve as lookup tables work for decimal numbers only because the digits zero through nine are contiguous in the ASCII table, and you can simply subtract Ord('0') from the ordinal value of the number you're dealing with to get its actual decimal value. The range of hex characters is NOT contiguous with the ten decimal numbers, and in fact is different based on whether the given hex digit is in upper- or lower-case. So you cannot use simple lookup tables to do this thinking that a range of 16 characters is going to work in all cases. It will work for the ten decimal characters, but NONE of the hex characters. And certainly not for strings expressed as 4-character BINARY (0 + 1) versions of hex digits!

 

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×