![]() |
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:
Ergebnis: 2097151
procedure TForm1.Button1Click(Sender: TObject);
var a: Integer; begin a := -1024 shr 11; Button1.Caption := IntToStr(a); end;
Code:
Ergebnis: -1
private void button1_Click(object sender, EventArgs e)
{ int a = -1024 >> 11; button1.Text = Convert.ToString(a); } Wie kommt es zu so einem unterschiedlichem Ergebnis? |
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.
|
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
C# benutzt einen arithmetic, Delphi einen logical shift:
![]() ![]() |
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. |
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.
|
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Zitat:
|
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Wieso?
Delphis SHR/SHL behandelt doch Signed und Unsigned gleich. Und er braucht doch SAR (ASM) :wink: |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Ich habe leider keine Ahnung von asm.
Kann mir das einer machen? |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Delphi-Quellcode:
ich hoff mal es stimmt
Function ArithmeticShiftRight(i: Integer; Shift: Byte): Integer;
ASM SAR EAX, DL End; [add]
Delphi-Quellcode:
Function ArithmeticShiftRight(i: Integer; Shift: Byte): Integer;
Begin Result := (i shr Shift) or (($FFFFFFFF * (i shr 31)) shl 32 - Shift) End; |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Wie wärs damit:
Delphi-Quellcode:
okay, asm is vll. n bisschen schneller :angel2:
// arithmetic shift
function arithmetic_shr(a: Integer; b: Byte): Integer; begin Result := Sign(a) * (abs(a) shr b); end; |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
@arithmetic_shr
und das geht? da frag ich mich, was ich da grad oben nachedieirt hab :oops: |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Zitat:
Bei -1024 shr 11 soll -1 rauskommen. Meine Funktion rechnet also: sign(-1024) * (abs(-1024) shr 11) = -1 * (1024 shr 11) = -1 * 1 = -1 |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
1024 shr 11 ist aber 0.
|
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... |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
ich muß zugeben, wir beide rechnen irgendwie wohl nicht so ganz richtig :oops:
Delphi-Quellcode:
zumindestens rechnen alle etwas anders (auch mal mit "i sar 8" probiert und da sieht es noch schlimmer aus)
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; [add] wegen der Operandengröße ... siehe 1. Funktion :angel: |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Juhu, mit der neuen ASM-Funktion geht es einwandfrei. Alle Werte sind korrekt. Dankeschön. :dp:
|
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Delphi-Quellcode:
Das rechnet jetzt auch korekt (hatte beim letzen SHL eine Klammer vergessen und die Multiplikation nun ohne Vorzeichen rechnen lassen)
Function ArithmeticShiftRight2(i: Integer; Shift: Byte): Integer;
Begin Result := (i shr Shift) or ((LongWord($FFFFFFFF) * LongWord(i shr 31)) shl (32 - Shift)); End; PS: @Apollonius: im positiven Bereich rechnet deines schon irgendwie richtig, nur nicht mit negativen i bzw. a |
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
Ich war's nicht. Ehrenwort. :mrgreen:
|
Re: Unterschiedliches Verhalten bei Bitverschiebung (C# / De
jfheins meinte ich :oops:
|
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 03:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz