Autor Beitrag
Frolo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Mo 01.04.13 23:24 
Hey,

mir ist, als ich nach dem Typ TColor folgende Seite aufgefallen: docs.embarcadero.com...Graphics_TColor.html

Da wird der Typ ganz lapidar so definiert:
ausblenden Delphi-Quelltext
1:
TColor = -$7FFFFFFF-1..$7FFFFFFF;					


Jetzt kamen mir ein paar Fragen auf:

1. Kann ich jetzt einen Typen TVeryLongInt = -$FFFFFFFFFFFFFFFFFFFFFFF..$FFFFFFFFFFFFFFFFFFFFFFF definieren?
2. Ich hab mir das immer so vorgestellt, dass ich einfach nur die Größe des Typs angebe, also zB. Char = $FF. Ich verstehe das - und .. nicht. Da wird irgendein Zahlenbereich angegeben oder? Nur was macht eine negative Zahl bei TColor für einen Sinn?
3. Warum 7F? Warum nicht einfach FF?
4. Was macht das -1 am Ende des ersten Elements?

Danke für eure Antworten :)
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Di 02.04.13 00:07 
Zu 1.) Ja, solange sich dein TVeryLongInt in irgendeinen bereits vordefinierten Variablentyp paßt. Der TColor paßt übrigens in einen integer.
Zu 2.) Korrekt erkannt, das ist ein Zahlenbereich. Betrachte die Zahlen mal Binär, dann wird das mit dem $7FFFFFFF schlagartig klar ;)
Zu 3.) Siehe 2a)
Zu 4.) Eins abziehen.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Di 02.04.13 10:23 
Ja okay, aber mir erschließt sich noch immer nicht, wieso man bei TColor nen negativen wert hat.. o: Vllt wäre es hilfreich, wenn ihr mir bei Integer zB zeigen könntet, wie zB -1 Hexadezimal bzw Binär aussieht :)

Außerdem ist es dann überhaupt möglich einen komplett neuen Zahlentyp mit sagen wir mal 16 Bytes zu "schaffen"?
knittel
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71
Erhaltene Danke: 2

Win XP, Win7, openSUSE
Delphi 7
BeitragVerfasst: Di 02.04.13 11:23 
Also du wirst es nicht schaffen können zum Beispiel einen Int128 einzubauen, da dieser nicht in einen bekannten Variablentyp passt (Int64 ist der größte in Delphi).

Um das mit den -1 zu erklären:
Wir nehmen dafür als einfaches Beispiel einfach mal einen ShortInt (selbe größe wie ein Byte)

Der sieht dann binär so aus:
00000000

Dieser besteht aus 8 Bits. Folglich gibt es 2^8 verschiedene Einstellungsmöglichkeiten. Das wären ausgrechnet 256.
Bei einem unsigned Byte (nur positive Zahlen) wäre das 0..255 in Dezimal oder in Hexadezimal $0..$FF.
Da wir aber einen signed Byte haben, haben wir sowohl positive als auch negative Zahlen.
Folglich würde man erst annehmen das es dann folgende Zahlen gibt -127..127 oder in Hexadezimal $-7F..$7F
Wenn wir jetzt aber genau aufpassen, werden wir merken, dass wir nur 255 Möglichkeiten ausnutzen (2 * 127 + 1(Die Null)) obwohl wir 256 haben. Deswegen macht
man bei dem ersten Teil noch ein -1 davor, damit man dann die Zahlen von -128..127 hat.

Intern wird das nämlich meist (eigentlich immer) über einen Bias geregt. Der Bias wäre hier zum Beispiel -128. Daher wäre folgender Wert 01000000 -> umgerechnet 64 -> Bias dazurechnen (64 - 128) -> -64.

_________________
"Wir können nicht fliehen!" "Wieso nicht?" "Sie haben mir die Schnürsenkel zusammengebunden!" "Die Schweine."

Für diesen Beitrag haben gedankt: Frolo
FaTaLGuiLLoTiNe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 200
Erhaltene Danke: 5

Windows 7, Windows 8.1
Delphi XE
BeitragVerfasst: Di 02.04.13 11:42 
user profile iconFrolo hat folgendes geschrieben Zum zitierten Posting springen:
Ja okay, aber mir erschließt sich noch immer nicht, wieso man bei TColor nen negativen wert hat..


Soweit ich weiss ist der negative Wertebereich von TColor für die Windows-Systemfarben reserviert.

_________________
<< FaTaLGuiLLoTiNe >>
Rhinoceroses don't play games!

Für diesen Beitrag haben gedankt: Frolo
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Di 02.04.13 12:52 
Bleiben noch 2 Fragen offen:

die erste wäre:

1. Wie stellt man negative Zahlen in hexadezimaler oder binärer Form da? 1 wäre ja 01 bzw $01 nur was wäre dann -1?

2. Wenn ich jetzt nen Int128 unbedingt bräuchte (ist ja kein Variablentyp vorhanden). Kann ich mir so einen nicht einfach selbst schreiben? Im Endeffekt ist es doch "nur" ein größerer Speicherbereich im Arbeitsspeicher oder?
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 02.04.13 13:21 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
 i:Integer;
begin
  For i := -5 to 5 do Memo1.Lines.Add (IntToHex(i,8) +'  -  ' + IntToStr(i));
end;


Wenn Du Dich an einem neuen Typen versuchen willst, kannst Du Dich ja mal da reinlesen docwiki.embarcadero....Overloading_(Delphi)

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS

Für diesen Beitrag haben gedankt: Frolo
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 174
Erhaltene Danke: 43



BeitragVerfasst: Di 02.04.13 13:48 
1.)
Wird das erste Zeichen als Vorzeichen betrachtet, wird die Binär ohne Vorzeichen darstellbare größte Zahl zur -1 (alle Bits sind gesetzt):
ausblenden Quelltext
1:
2:
3:
4:
Hexadezimal:                   $80 -      $FF,      $00 -      $7F
Binär:                    10000000 - 11111111, 00000000 - 01111111 
vorzeichenlos Dezimal:         128 -      255,        0 -      127 
vorzeichenbehaftete Dez.:     -128 -       -1,        0 -      127


2.)
Der Compiler kennt keine Operationen mit denen er solche Zahlen verarbeiten kann.
Aktuelle Compilerversionen erlauben aber die Definition eigener Operatoren für Records.

Kleines Beispiel zur Summierung sehr langer Zahlen:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
unit BigNum;

interface

type
  TBigNum = record
    Count: Integer;
    Data: array of Longword;
    class operator Add(v1, v2: TBigNum): TBigNum;
    class operator Equal(v1, v2: TBigNum): Boolean;
    class operator Implicit(const v1: TBigNum): AnsiString;
    class operator Implicit(const v1: AnsiString): TBigNum;
    procedure Add(const v1: TBigNum);
  end;

implementation

uses
  SysUtils;

class operator TBigNum.Implicit(const v1: TBigNum): AnsiString;
var
  n: Integer;
  p: PByte;
  pc: PChar;
  b: Byte;
begin
  n := v1.Count;
  if n = 0 then
    Result := '0'
  else
  begin
    p := @(v1.Data[n div 8]);
    Inc(p, (n mod 8div 2);
    SetLength(Result, n);
    pc := @(Result[1]);

    if Odd(n) then
    begin
      b := p^;
      Dec(p);
      pc^ := Char(b + Ord('0'));
      Inc(pc);
      Dec(n);
    end;
    while n > 0 do
    begin
      b := p^;
      Dec(p);
      pc^ := Char((b div 10) + Ord('0'));
      Inc(pc);
      pc^ := Char((b mod 10) + Ord('0'));
      Inc(pc);
      Dec(n, 2);
    end;
  end;
end;

class operator TBigNum.Implicit(const v1: AnsiString): TBigNum;
var
  n1, n2, i: Integer;
  s: AnsiString;
  b: Byte;
  pb: PByte;
  pc: PChar;
{---}
  function NextCharValue: Byte;
  begin
    if n1 <= 0 then
      Result := 0
    else
    begin
      Result := Ord(pc^) - Ord('0');
      if not (Result in [0..9]) then
         raise Exception.Create('Ungültige Zeichenfolge');
      Dec(pc);
      Dec(n1);
    end
  end;
{---}
begin
  s := Trim(v1);
  n1 := Length(s);
  Result.Count := n1;
  try
    n2 := (n1 + 7div 8;
    if Length(Result.Data) < n2 then
      SetLength(Result.Data, n2);

    pc := @(s[n1]);
    pb := @(Result.Data[0]);
    for i := 0 to (n2 * 4) - 1 do
    begin
      b := NextCharValue;
      b := NextCharValue * 10 + b;
      pb^ := b;
      Inc(pb);
    end;
  except
    Result.Count := 0;
    raise;
  end;
end;

procedure TBigNum.Add(const v1: TBigNum);
{---}
  function GetValue(p: PByte; var n: Integer): Byte; inline;
  begin
    if n = 0 then
      Result := 0
    else
    begin
      Result := p^;
      Dec(n);
    end;
  end;
{---}
var
  p1, p2: PByte;
  n1, n2, n, i: Integer;
  b1, b2, c: Byte;
begin
  n1 := Count;
  n2 := v1.Count;
  if n1 > n2 then
    n := n1
  else
    n := n2;
  if n > Length(Data) then
    SetLength(Data, n);

  p1 := PByte(Data);
  p2 := PByte(v1.Data);
  c := 0;
  for i := 0 to n - 1 do
  begin
    b1 := GetValue(p1, n1);
    b2 := GetValue(p2, n2);
    b1 := b1 + b2 + c;
    c  := b1 div 100;
    b1 := b1 mod 100;
    p1^ := b1;
    Inc(p1);
    Inc(p2);
  end;
  {Übertrag neue Stelle}
  if c <> 0 then
  begin
    Inc(n);
    if n > Length(Data) then
      SetLength(Data, n);
    Data[n - 1] := c;
  end;
  Count := n;
end;

class operator TBigNum.Add(v1, v2: TBigNum): TBigNum;
begin
  Result.Data  := Copy(v1.Data);
  Result.Count := v1.Count;
  Result.Add(v2);
end;

class operator TBigNum.Equal(v1, v2: TBigNum): Boolean;
begin
  Result := (v1.Count = v2.Count) and
    CompareMem(Pointer(v1.Data), Pointer(v2.Data),
               v1.Count * SizeOf(v1.Data[0]));
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
uses
  BigNum;

var
  a, b: TBigNum;
  c: string;
begin
  a := '1234567890123456789012345678901234567890123456789012345678901234567890';
  b := '0987654321098765432109876543210987654321098765432109876543210987654321';
  c := a + b;
  writeln(c);
end;

Für diesen Beitrag haben gedankt: Frolo
Frolo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 48



BeitragVerfasst: Di 02.04.13 20:30 
Vielen Dank für die Antworten. Ich hab nur die binäre Darstellung von negativen Zahlen nicht verstanden. Nehmen wir mal ein Byte und sagen es soll von -128 bis 127 gehen (ka ob das unsigned oder so heißt :D ) Wie sehen da zB -128, 0, -1, 1, 127 und 64 oder -64 aus? Ich brauch anscheinend Beispiele.

Bei positiven Werten ist das ja klar: Also Byte (0..255)

0 -> 0000 0000
1 -> 0000 0001
255 -> 1111 1111

Aber bei negativen :D
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Di 02.04.13 20:31 
Moin,

schau mal hier:

de.wikipedia.org/wiki/Zweierkomplement

Gruß