Emmerisch 0 Posted May 12, 2023 (edited) 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. Edited May 12, 2023 by Emmerisch Share this post Link to post
Uwe Raabe 2057 Posted May 12, 2023 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. 1 Share this post Link to post
David Schwartz 426 Posted May 12, 2023 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 = 1 Share this post Link to post
Emmerisch 0 Posted May 13, 2023 (edited) 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 May 13, 2023 by Emmerisch Share this post Link to post
Emmerisch 0 Posted May 13, 2023 (edited) if you count with 0 both are 15 Edited May 13, 2023 by Emmerisch Share this post Link to post
programmerdelphi2k 237 Posted May 13, 2023 (edited) @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 May 13, 2023 by programmerdelphi2k Share this post Link to post
programmerdelphi2k 237 Posted May 13, 2023 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
programmerdelphi2k 237 Posted May 13, 2023 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
programmerdelphi2k 237 Posted May 13, 2023 3 hours ago, Emmerisch said: Number of elements is different from declaration 1 Share this post Link to post
programmerdelphi2k 237 Posted May 13, 2023 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
PeterBelow 238 Posted May 14, 2023 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
programmerdelphi2k 237 Posted May 14, 2023 (edited) 1 hour ago, PeterBelow said: string literals is the same. and Chars is not a "Ordinals"? Edited May 14, 2023 by programmerdelphi2k Share this post Link to post
PeterBelow 238 Posted May 15, 2023 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. 3 Share this post Link to post
programmerdelphi2k 237 Posted May 15, 2023 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
David Heffernan 2345 Posted May 15, 2023 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. 1 Share this post Link to post
David Schwartz 426 Posted May 16, 2023 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! 2 Share this post Link to post