AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Warum ist bei dem negativen Integer das erste Bit 0?
Thema durchsuchen
Ansicht
Themen-Optionen

Warum ist bei dem negativen Integer das erste Bit 0?

Ein Thema von Alallart · begonnen am 27. Mär 2024 · letzter Beitrag vom 28. Mär 2024
Antwort Antwort
Alallart

Registriert seit: 8. Dez 2015
153 Beiträge
 
#1

Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 27. Mär 2024, 21:03
Integer ist ein Variablentyp mit Vorzeichen (d.h. Plus/Minus). Das Vorzeichen wird meiner Kenntnis nach mit einem Bit gegenzeichnet, d. h. ist das erst Bit, von links gesehen, eine 0, dann ist die Zahl positiv. Ist es eine 1, ist die Zahl negativ. Für den Wert sind von den 32 Bit eines Integers nur 31 Bit nutzbar. Das 32'ste Bit ist für das Vorzeichen.

Das wollte ich mal überprüfen und habe den Code geschrieben. Allerdings ist das erste Bit immer eine 0, egal was für ein Wert ich nehme, positiv oder negativ. Wo liegt mein Fehler?
Delphi-Quellcode:
function BitAtPos(BitPos: Byte): Integer;
begin
  Result := 0;
  if (BitPos <= (SizeOf(Integer) * 8)) and (BitPos > 0) then
    Result := Integer(1) shl (BitPos - 1);
end;

//Liefert einen Binär-String aus 0 und 1 im Wert von Integer zurück.
function IntToBinStr(Int: Integer): string;
const
  b: array[Boolean] of Char = ('0', '1');
var
  i: Integer;
begin
  Result := '';
  for i := 1 to (SizeOf(Int) * 8) do
    Result := b[(Int and BitAtPos(i)) > 0] + Result;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(IntToBinStr(-214748364));
end;
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
662 Beiträge
 
#2

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 27. Mär 2024, 23:08
So scheint es zu gehen:

function BitAtPos(BitPos: Byte): NativeUInt;
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 27. Mär 2024, 23:21
Oder auch so:
Delphi-Quellcode:
function IntToBinStr(Value: integer): string;
const
  BITS_PER_BYTE = 8;
  BIT_CHARS: array [Boolean] of char = ('0', '1');
var
  lLen: integer;
  i: integer;
begin
  lLen := BITS_PER_BYTE * SizeOf(Value);
  SetLength(Result, lLen);
  for i := High(Result) downto Low(Result) do
    begin
      Result[i] := BIT_CHARS[Value and 1 = 1];
      Value := Value shr 1;
    end;
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.147 Beiträge
 
Delphi 12 Athens
 
#4

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 02:05
Dein BitAtPos liefert einen Integer zurück.
Delphi-Quellcode:
b[(Int and BitAtPos(i)) <> 0]
                        ^^
Alternativ wäre es mit einem Cardinal so auch korrekt funktional.


Zitat:
Das Vorzeichen wird meiner Kenntnis nach mit einem Bit gegenzeichnet
Jain, aber im Prinzip kann man an dem Bit zumindestens erkennen, ob es negativ ist.
https://de.wikipedia.org/wiki/Zweierkomplement

Delphi-Quellcode:
function BitAtPos(BitPos: Byte): Integer;
begin
  Result := $1 shl BitPos;
end;

//Liefert einen Binär-String aus 0 und 1 im Wert von Integer zurück.
function IntToBinStr(Int: Integer): string;
const
  b: array[Boolean] of Char = ('0', '1');
var
  i: Integer;
begin
  Result := '';
  for i := 0 to SizeOf(Int) * 8 - 1 do
    Result := b[Int and ($1 shl i) <> 0] + Result;
end;
Delphi-Quellcode:
function IntToBinStr(Int: Integer): string;
const
  b: array[Boolean] of Char = ('0', '1');
var
  i: Integer;
begin
  Result := '';
  for i := 0 to SizeOf(Int) * 8 - 1 do
    Result := b[Odd(Int shr i)] + Result;
end;
Delphi-Quellcode:
function IntToBinStr(Int: Integer): string;
const
  b: array[Boolean] of Char = ('0', '1');
var
  i: Integer;
begin
  SetLength(Result, SizeOf(Int) * 8);
  for i := 0 to SizeOf(Int) * 8 - 1 do
    Result[i + Low(string)] := b[Odd(Int shr i)];
end;


Über Int als Bezeichner könnte man noch streiten, denn Delphi-Referenz durchsuchenInt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 02:08 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#5

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 06:35
Dein BitAtPos liefert einen Integer zurück.
Aber war das nicht die Frage?

Integer und Cardinal sind beide 32-Bit und nehmen den gleichen MemorySpace ein.
Nur dass Integer von außen als positiv oder negativ interpretiert wird und Cardinal als ausschließlich positiv,
der eigentliche Speicherbereich ist aber nach wie vor gleich.

Ich vermute, dass es an auch dieser Zeile liegt, wo das shl eben nicht das Integer richtig weiterschieben kann.

  Result := Integer(1) shl (BitPos - 1); Ja, das ganze als Cardinal oder UInt32 sollte das lösen.

Ich habe die Frage aber so verstanden, warum die Zeile oben eben bei Integer das Bit nicht richtig weiterschiebt, bei Cardinal aber doch.

https://www.oreilly.com/library/view...595/re295.html

Geändert von Rollo62 (28. Mär 2024 um 06:40 Uhr)
  Mit Zitat antworten Zitat
Alallart

Registriert seit: 8. Dez 2015
153 Beiträge
 
#6

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 06:56
Vielen Dank, hat beim Integer (32) funktioniert. Der Tipp von Olli73 bezüglich Variablentyp-Änderung auf NativeUInt hat das Problem gelöst, zumindest beim Integer. Somit ist das Hauptproblem gelöst, mit dem ich zur Not leben kann.

Eigentlich wollte ich das für einige Variablentypen schreiben. Ein Schüler bat mich drum gebeten, für sein Informatik-Unterricht. Die Schüler wollen überprüfen ob die Bits, mit denen sie rechnen (Binärrechnen), tatsächlich so auch im Computer gespeichert werden.

Die Version von DeddyH hat meine Version elegant verkleinert, und sie funktioniert bei Integer wunderbar.

Jetzt versuche ich das Int64. Da habe ich noch meine Probleme.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.147 Beiträge
 
Delphi 12 Athens
 
#7

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 08:23
Ja, zum Integer passt aber eben nicht das > , da das größte Bit nunmal negativ ist (MinInt), weswegen ein <> eben richtiger wäre.
Aber da beim Cardinal alle Werte immer größer als 0 sind, passt dort auch das > , nur muß man eben vorher erstmal casten.

PS: NativeUInt ist in Win32 ein Cardinal.
Aber da es hier um 32 Bit geht, ist es z.B. für Win64 kompiliert aber komplett falsch.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 08:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.011 Beiträge
 
Delphi 12 Athens
 
#8

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 08:31
Ein alternativer Ansatz wäre:
Delphi-Quellcode:
  for i := 0 to (SizeOf(Int) * 8) - 1 do
    Result := b[i in TIntegerSet(Int)] + Result;
mit
Delphi-Quellcode:

TIntegerSet = set of 0..SizeOf(Integer) * 8 - 1;
aus System.SysUtils.

Das lässt such auch problemlos auf Int64 erweitern, wobei man dann
Delphi-Quellcode:

TInt64Set = set of 0..SizeOf(Int64) * 8 - 1;
halt selbst deklarieren muss.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.147 Beiträge
 
Delphi 12 Athens
 
#9

AW: Warum ist bei dem negativen Integer das erste Bit 0?

  Alt 28. Mär 2024, 08:41
PS: Wenn du den Code genau so 1:1 mit NativeUInt oder Cardinal kompilierst, wie in #2 erwähnt, also fröhlich Signed und Unsigned vermischst, dann könnte dir der Code spätestens in einem "neuen" Projekt ab Delphi 11 (oder 10) vielleicht wunderschön knallen, beim nun standardmäßig aktivem RangeCheck.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 08:48 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz