Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Unterschiedliches Verhalten bei Bitverschiebung (C# / Delphi (https://www.delphipraxis.net/135975-unterschiedliches-verhalten-bei-bitverschiebung-c-delphi.html)

WorstNightmare 21. Jun 2009 13:54


Unterschiedliches Verhalten bei Bitverschiebung (C# / Delphi
 
Hallo,

ich übersetze gerade mal wieder ein Programm von C# nach Delphi. Da das Resultat nicht so funktionierte wie es sollte, habe ich nach dem Fehler gesucht und ihn auch gefunden:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  a: Integer;
begin
  a := -1024 shr 11;
  Button1.Caption := IntToStr(a);
end;
Ergebnis: 2097151

Code:
        private void button1_Click(object sender, EventArgs e)
        {
            int a = -1024 >> 11;
            button1.Text = Convert.ToString(a);
        }
Ergebnis: -1

Wie kommt es zu so einem unterschiedlichem Ergebnis?

SirThornberry 21. Jun 2009 14:02

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
also mir ist das c# Ergebnis schleierhaft. Wenn eine Zahl negativ ist so ist das höchste bit gesetzt. Und wenn man nach rechts shiftet sollte dieses Bit mit wandern. Entsprechend sollte bereits beim Shiften um 1 nach Rechts keine negative Zahl das Ergebnis sein da eben das "NegativBit" weg geshiftet wurde.

Khabarakh 21. Jun 2009 14:08

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
C# benutzt einen arithmetic, Delphi einen logical shift:
http://en.wikipedia.org/wiki/Bitwise...ion#Bit_shifts
https://newsgroups.codegear.com/thre...?threadID=5367

himitsu 21. Jun 2009 14:11

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Dann wirst du da wohl etwas selber basteln müssen,
also entweder dir das Ergebnis entsprechende selber berechnen
oder auf ASM ausweichen.

SirThornberry 21. Jun 2009 14:12

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Ich glaub ich hab müll gepostet - das höchste bit steht doch gar nicht für Minus - es wird Zeit das ich mir das mal wieder etwas genauer ansehe.

Dax 21. Jun 2009 14:16

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Zitat:

Zitat von himitsu
Dann wirst du da wohl etwas selber basteln müssen,
also entweder dir das Ergebnis entsprechende selber berechnen
oder auf ASM ausweichen.

Auf UInt casten reicht.

himitsu 21. Jun 2009 14:24

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Wieso?

Delphis SHR/SHL behandelt doch Signed und Unsigned gleich.

Und er braucht doch SAR (ASM) :wink:

WorstNightmare 21. Jun 2009 14:29

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Ich habe leider keine Ahnung von asm.
Kann mir das einer machen?

himitsu 21. Jun 2009 14:40

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Delphi-Quellcode:
Function ArithmeticShiftRight(i: Integer; Shift: Byte): Integer;
  ASM
    SAR EAX, DL
  End;
ich hoff mal es stimmt

[add]
Delphi-Quellcode:
Function ArithmeticShiftRight(i: Integer; Shift: Byte): Integer;
  Begin
    Result := (i shr Shift) or (($FFFFFFFF * (i shr 31)) shl 32 - Shift)
  End;

jfheins 21. Jun 2009 14:42

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Wie wärs damit:
Delphi-Quellcode:
// arithmetic shift
function arithmetic_shr(a: Integer; b: Byte): Integer;
begin
  Result := Sign(a) * (abs(a) shr b);
end;
okay, asm is vll. n bisschen schneller :angel2:

himitsu 21. Jun 2009 14:45

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
@arithmetic_shr

und das geht?
da frag ich mich, was ich da grad oben nachedieirt hab :oops:

jfheins 21. Jun 2009 15:09

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Zitat:

Zitat von himitsu
@arithmetic_shr

und das geht?
da frag ich mich, was ich da grad oben nachedieirt hab :oops:

Keine Ahnung, aber es könnte klappen ;)

Bei -1024 shr 11 soll -1 rauskommen.

Meine Funktion rechnet also:

sign(-1024) * (abs(-1024) shr 11)
= -1 * (1024 shr 11)
= -1 * 1
= -1

Apollonius 21. Jun 2009 15:17

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
1024 shr 11 ist aber 0.

WorstNightmare 21. Jun 2009 15:21

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Alsoo mal im Überblick:
arithmetic_shr (jfheins) ergibt immer 0; bei einigen Werten muss man -7 rechnen, dann stimmt die Zahl mit C# überein
ArithmeticShiftRight (asm) kompiliert nicht (Operandengröße stimmt nicht)
ArithmeticShiftRight (delphi) scheint zu funktionieren, da muss ich nochmal kucken, ich glaube bei anderen Werten geht sie nicht...

himitsu 21. Jun 2009 15:25

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
ich muß zugeben, wir beide rechnen irgendwie wohl nicht so ganz richtig :oops:

Delphi-Quellcode:
Function ArithmeticShiftRight(i: Integer; Shift: Byte): Integer;
  ASM
    MOV CL, DL
    SAR EAX, CL
  End;

Function ArithmeticShiftRight2(i: Integer; Shift: Byte): Integer;
  Begin
    Result := (i shr Shift) or (($FFFFFFFF * (i shr 31)) shl 32 - Shift)
  End;

function arithmetic_shr(a: Integer; b: Byte): Integer;
begin
  Result := Sign(a) * (abs(a) shr b);
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  for i := -1024 to 1024 do
    Memo1.Lines.Add(Format('%d: %d %d %d', [i,
      ArithmeticShiftRight (i, 11),
      ArithmeticShiftRight2(i, 11),
      arithmetic_shr      (i, 11)
    ]));
end;
zumindestens rechnen alle etwas anders (auch mal mit "i sar 8" probiert und da sieht es noch schlimmer aus)

[add]
wegen der Operandengröße ... siehe 1. Funktion :angel:

WorstNightmare 21. Jun 2009 15:29

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Juhu, mit der neuen ASM-Funktion geht es einwandfrei. Alle Werte sind korrekt. Dankeschön. :dp:

himitsu 21. Jun 2009 15:36

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Delphi-Quellcode:
Function ArithmeticShiftRight2(i: Integer; Shift: Byte): Integer;
  Begin
    Result := (i shr Shift) or ((LongWord($FFFFFFFF) * LongWord(i shr 31)) shl (32 - Shift));
  End;
Das rechnet jetzt auch korekt (hatte beim letzen SHL eine Klammer vergessen und die Multiplikation nun ohne Vorzeichen rechnen lassen)

PS: @Apollonius: im positiven Bereich rechnet deines schon irgendwie richtig,
nur nicht mit negativen i bzw. a

Apollonius 21. Jun 2009 15:39

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Ich war's nicht. Ehrenwort. :mrgreen:

himitsu 21. Jun 2009 15:41

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
jfheins meinte ich :oops:

jfheins 21. Jun 2009 15:43

Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
 
Du meinst sicher mich :stupid:

Ja - das Problem ist: x shr n ist ja wie eine Division x / 2^n die nach unten abgerundet wird (richtung -Unenedlich).

d.h. bei 1024 shr 11 shift kommt 0,5 raus und das wird auf 0 gerundet. (-0,5 würde auf das richtige Ergebnis -1 gerundet werden)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:02 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