Autor |
Beitrag |
Frolo
      
Beiträge: 48
|
Verfasst: 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:
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
      
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: 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 
      
Beiträge: 48
|
Verfasst: 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
      
Beiträge: 71
Erhaltene Danke: 2
Win XP, Win7, openSUSE
Delphi 7
|
Verfasst: 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
      
Beiträge: 200
Erhaltene Danke: 5
Windows 7, Windows 8.1
Delphi XE
|
Verfasst: Di 02.04.13 11:42
Frolo hat folgendes geschrieben : | 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 
      
Beiträge: 48
|
Verfasst: 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
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Di 02.04.13 13:21
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
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: 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):
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:
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 8) div 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 + 7) div 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; 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; |
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 
      
Beiträge: 48
|
Verfasst: 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  ) 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 
|
|
FinnO
      
Beiträge: 1331
Erhaltene Danke: 123
Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
|
Verfasst: Di 02.04.13 20:31
|
|
|