Negativen Wert in Hexadezimal oder Binär umwandeln
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Muss das sein, dass du einen Anfänger mit PChar und pointer verwirrst? Es geht doch auch mit strinknormalen Indizes.
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Mit normalen Indizes wird bei jeder Zeichenzuweisung ein String-unique-Test durchgeführt (copy on write) was der Performance nicht eben zuträglich ist.
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Das ist schon klar. Aber dem OP geht es nicht um das "beste" oder "schnellste" Verfahren, sondern darum, wie es überhaupt funktioniert. Und dazu ist die Optimierung mit PChar unnötig und für einen Anfänger extrem verwirrend. Er wird ohnehin auch schon an den SHR und AND Operationen zu knabbern haben.
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Du sagt es.wp_xyz hat geschrieben:Er wird ohnehin auch schon an den SHR und AND Operationen zu knabbern haben.
Genau. Ich will es erstmal verstehen wie es funktioniert. Optimieren kann man es noch immer, wenn ich das Prinzip und die Sprache besser verstehe.wp_xyz hat geschrieben:Das ist schon klar. Aber dem OP geht es nicht um das "beste" oder "schnellste" Verfahren, sondern darum, wie es überhaupt funktioniert. Und dazu ist die Optimierung mit PChar unnötig und für einen Anfänger extrem verwirrend.
Und wo ich bei verstehen bin, weiß ich nicht was die FP-IntToHex-Funktion soviel besser macht (abgesehen davon das sie auch mit negativen Werten funktioniert) bzw. wieso sie schneller ist. Aber das werden ich hoffentlich später verstehen.
Ich bin gerade mit Hilfe des Wiki-Links, am werkeln einer simplen/dummen Lösung.
Nachtrag:
Meine Idee ist für die Katz.

Das Problem ist ja, das ich keinen negativen Integer-Wert in einen Binärcode umwandeln kann kann.
Das einzige was mir einfällt ist, abfragen ob der Wert negativ ist, und wenn er es, den Abschnitt den ich zum umwandeln von Positiven Werten nutze irgendwie rückwärts laufen lasse. Irgendwo steckt da die Lösung drinne.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Kleiner Denkanstoß:
Code: Alles auswählen
ShowMessage(IntToStr(Cardinal(-1))); //oder writeln
ShowMessage(IntToStr(Integer(-1)));
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Wies funktioniert:
Zahlen in Computerprogrammen sind aus Bits zusammengesetzt. Ein Bit ist die kleinstmögliche Informationseinheit und kann nur zwei Zustände einnehmen, z.B. 0 oder 1. Übliche Zahlengrössen sind 8, 16, 32 und 64 Bits.
Um die Bits solcher Zahlen übersichtlich darzustellen werden jeweils vier Bits zu einem Zeichen zusammengefasst:
Die Tabelle
macht diese Zuweisung.
Nun geht es noch darum, die einzelnen Vierergruppen auf die Zeichen im Ergebnisstring zu verteilen. z.B. für 32 Bit:
Die "shr" Operationen schieben jeweils eine Vierergruppe auf die
Bits 0..3, die "and $f" Operationen blenden alle anderen Bits aus, da $f = 0000000000001111 ist.
Die Bits einer Variablen können z.B. als positive Zahl oder als positiv/negativ-Ganzzahl interpretiert werden.
Im ersten Fall ist der Wertebereich einer 8-Bit Zahl 0..255. 0 ist dabei alle 8 Bits 0, 255 = 1+2+4+8+16+32+64+128 das heisst alle 8 Bits = 1.
Negative Zahlen werden im sogenannten Zweierkomplement dargestellt. Der positive Bereich ist zu den normalen Ganzzahlen identisch.
Um -1 darzustellen zieht man von 0 eins ab und kommt im Falle von 8 Bit zu 11111111. Das wird fortgeführt bis -128 = 10000000. -129 ergäbe 0111111 was mit +127 übereinstimmt und daher einen Überlauf bedeutet. Der Zweierkomplement Wertebereich einer 8-Bit Zahl ist daher -128..+127.
Zahlen in Computerprogrammen sind aus Bits zusammengesetzt. Ein Bit ist die kleinstmögliche Informationseinheit und kann nur zwei Zustände einnehmen, z.B. 0 oder 1. Übliche Zahlengrössen sind 8, 16, 32 und 64 Bits.
Um die Bits solcher Zahlen übersichtlich darzustellen werden jeweils vier Bits zu einem Zeichen zusammengefasst:
Code: Alles auswählen
(0) 0000 -> 0
(1) 0001 -> 1
(2) 0010 -> 2
...
(9) 1001 -> 9
(10) 1010 -> a
(11) 1011 -> b
...
(15) 1111 -> f
Code: Alles auswählen
const
charhexlower: array[0..15] of char =
('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
Nun geht es noch darum, die einzelnen Vierergruppen auf die Zeichen im Ergebnisstring zu verteilen. z.B. für 32 Bit:
Code: Alles auswählen
Bitnummer 31..28 27..24 23..20 19..16 15..12 11..8 7..4 3..0
Beispiel 0001 0010 0011 0100 0101 0110 0111 1000
Wert 1 2 3 4 5 6 7 8
Zeichennummer 0 1 2 3 4 5 6 7
Zeichennummer 01234567
Resultat '12345678'
Bits 0..3, die "and $f" Operationen blenden alle anderen Bits aus, da $f = 0000000000001111 ist.
Die Bits einer Variablen können z.B. als positive Zahl oder als positiv/negativ-Ganzzahl interpretiert werden.
Im ersten Fall ist der Wertebereich einer 8-Bit Zahl 0..255. 0 ist dabei alle 8 Bits 0, 255 = 1+2+4+8+16+32+64+128 das heisst alle 8 Bits = 1.
Negative Zahlen werden im sogenannten Zweierkomplement dargestellt. Der positive Bereich ist zu den normalen Ganzzahlen identisch.
Um -1 darzustellen zieht man von 0 eins ab und kommt im Falle von 8 Bit zu 11111111. Das wird fortgeführt bis -128 = 10000000. -129 ergäbe 0111111 was mit +127 übereinstimmt und daher einen Überlauf bedeutet. Der Zweierkomplement Wertebereich einer 8-Bit Zahl ist daher -128..+127.
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Und hier noch die Umsetzung von mse's Verfahren in "normale" Strings mit Indices:
Code: Alles auswählen
const
charhex: array[0..15] of char =
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
charhexlower: array[0..15] of char =
('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
[...]
function valtohex(const avalue: byte): string;
begin
setlength(result,2);
result[1} := charhexlower[avalue shr 4];
result[2] := charhexlower[avalue and $f];
end;
function valtohex(const avalue: word): string;
begin
setlength(result,4);
result[1] := charhexlower[avalue shr 12];
result[2] := charhexlower[(avalue shr 8) and $f];
result[3] := charhexlower[(avalue shr 4) and $f];
result[4] := charhexlower[avalue and $f];
end;
function valtohex(const avalue: longword): string;
begin
setlength(result,8);
result[1] := charhexlower[avalue shr 28];
result[2] := charhexlower[(avalue shr 24) and $f];
result[3] := charhexlower[(avalue shr 20) and $f];
result[4] := charhexlower[(avalue shr 16) and $f];
result[5] := charhexlower[(avalue shr 12) and $f];
result[6] := charhexlower[(avalue shr 8) and $f];
result[7] := charhexlower[(avalue shr 4) and $f];
result[8] := charhexlower[avalue and $f];
end;
function valtohex(const avalue: qword): string;
begin
result:= valtohex(avalue shr 32)+valtohex(avalue);
end;
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Natürlich kannst du das. Schau dir die Tabelle auf https://de.wikipedia.org/wiki/Zweierkomplement an. Da siehst du, dass ein und dasselbe Bitmuster einmal als positive und einmal als negative Zahl betrachtet werden kann. In dem Text steht, wie man die negative und positive Zahlen mit demselben Bitmuster ineinander umwandeln kann. Bestimme also die positive Zahl, die dasselbe Bitmuster hat wie deine negative und stecke die positive in deine Konvertierungsroutine. (oder lass das den Compiler machen, indem du deiner Routine einen vorzeichenLOSEN Integer-Typ übergibst).Nixsager hat geschrieben: Das Problem ist ja, das ich keinen negativen Integer-Wert in einen Binärcode umwandeln kann kann.
Das einzige was mir einfällt ist, abfragen ob der Wert negativ ist, und wenn er es, den Abschnitt den ich zum umwandeln von Positiven Werten nutze irgendwie rückwärts laufen lasse. Irgendwo steckt da die Lösung drinne.
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Die binäre Darstellung kann man z.B. so machen:
Wie ich sehe gibt es da noch Optimierungsbedarf. 
Code: Alles auswählen
function bintostr(inp: longword; digits: integer): string;
//convert longword to binstring, digits = bit count
var
int1: integer;
begin
setlength(result,digits);
for int1:= digits downto 1 do begin
result[int1]:= char(ord('0') + (inp and $1));
inp:= inp shr 1;
end;
end;

-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
Da bin ich dabei.
Mir ist nachdem ich den Post erweitert habe aufgefallen, dass ich den Binären Code nach dieser Methode nur umwandeln muss.
Dazu mache ich mir gerade erstmal eine For-Schleife mit If-Abfrage.
Und in der Rechenmethode, die ich im ersten Post geschrieben habe, habe ich ein If-Abfrage geschrieben die ein -1 in ein 1 umwandelt, Weil ich ja den Restwert direkt an einer String-Variabel weiter gebe.
@mse
Das mit shr und so, will erst machen wenn ich es kapiert habe.
Wenn meine Erweiterung funktioniert, werde ich sie posten, und dann könnt ihr den Kopf schütteln.
Mir ist nachdem ich den Post erweitert habe aufgefallen, dass ich den Binären Code nach dieser Methode nur umwandeln muss.
Dazu mache ich mir gerade erstmal eine For-Schleife mit If-Abfrage.
Und in der Rechenmethode, die ich im ersten Post geschrieben habe, habe ich ein If-Abfrage geschrieben die ein -1 in ein 1 umwandelt, Weil ich ja den Restwert direkt an einer String-Variabel weiter gebe.
@mse
Das mit shr und so, will erst machen wenn ich es kapiert habe.
Wenn meine Erweiterung funktioniert, werde ich sie posten, und dann könnt ihr den Kopf schütteln.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!
-
- Beiträge: 168
- Registriert: Sa 8. Okt 2016, 08:38
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Polska
Re: Negativen Wert in Hexadezimal oder Binär umwandeln
So ich habe meinen Code erweitert.
Jetzt könnt ihr den Kopf schütteln.
Für Tipps zur optimierung ohne SHR und sowas wäre ich dankbar.
Es muss ich nur noch schauen wie ich das jetzt bei meiner IntToHex-Funktion umsetzte.
Ich habe mir von FP IntToBin und IntToHex angeschaut, weil ich wissen wollte wie schneller der Code im Vergleich zu meinem ist.
Die kann man nicht 1 zu 1 übernehmen. Denn TP hat kein SetLength und kein UInt32.
IntToHex scheint ansazuweise zu funktionieren, aber IntToBin funktioniert nicht.
Und davon mal abgesehen verstehe ich den Code nicht.
Danke nochmal an c18x37.
Daran gedacht hatte ich schon, sowas in der Richtung zu machen. Aber war gut das du mich in die Richtung weiter geschubst hast.
Jetzt könnt ihr den Kopf schütteln.
Code: Alles auswählen
If NegativStatusValue = 1 then
begin
I := 32;
Repeat
If FirstZeroValue = 0 Then
Case BinResultValueTemp[I] of
'0':
CharValueTemp := '0';
'1':
begin
CharValueTemp := '1';
FirstZeroValue := 1;
end;
end
else
Case BinResultValueTemp[I] of
'0':
CharValueTemp := '1';
'1':
CharValueTemp := '0';
end;
BinResultValueTemp2 := CharValueTemp + BinResultValueTemp2;
Dec(I);
Until I = 0;
BinResultValueTemp := BinResultValueTemp2;
end;
Es muss ich nur noch schauen wie ich das jetzt bei meiner IntToHex-Funktion umsetzte.
Ich habe mir von FP IntToBin und IntToHex angeschaut, weil ich wissen wollte wie schneller der Code im Vergleich zu meinem ist.
Die kann man nicht 1 zu 1 übernehmen. Denn TP hat kein SetLength und kein UInt32.
IntToHex scheint ansazuweise zu funktionieren, aber IntToBin funktioniert nicht.
Und davon mal abgesehen verstehe ich den Code nicht.
Danke nochmal an c18x37.
Daran gedacht hatte ich schon, sowas in der Richtung zu machen. Aber war gut das du mich in die Richtung weiter geschubst hast.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!