Re: Vorzeichen entfernen
@frank: Nicht nur exotisch, sondern auch falsch.
-1: $FFFFFFFF Oberstes Bit auf 0 gesetzt: $7FFFFFFF Und $7FFFFFFF ist 2^31-1, also ungefähr 2 Mrd. und nicht, wie gewünscht, 1. Wenn schon, dann müsste man es so machen:
Delphi-Quellcode:
Oder, der schnellere Assembler-Weg:
if x<0 then x:=not x + 1;
Code:
cdq eax
xor eax, edx sub eax, edx |
Re: Vorzeichen entfernen
Zitat:
|
Re: Vorzeichen entfernen
gut, dann hatte ich das mal falsch verstanden, :roll:
dachte bei signed wird das vorzeichen im höchstwertigen Bit gespeichert und der rest bleibt... jetzt hab ich mich aber mal blamiert... :oops: aber jetzt wo ihrs sagt, fällt mir grade ein, dass ich beim Zerlegen von Binärdateien schon drüber gestolpert bin, dass 0xFFFFFFFF = -1 ist. stimmt das
Delphi-Quellcode:
immer? also bei allen signed datentypen?
if x<0 then x:=not x + 1;
auch wenn mir der asm-weg noch bisschen Probleme bereitet, trotz asm buch vor mir... wenn ich das richtig verstehe, müsste cdq ja das höchstwertige bit von eax in alle bits von edx schreiben.... also
Code:
bzw.
edx eax
$FFFFFFFF $FFFFFFFF
Code:
xor setzt dann bei ersterem eax auf $0, da eax=edx.
$00000000 $7FFFFFFF
jetzt subtrahiere ich edx von eax also $0-$FFFFFFFF...und da kommt 1 raus? beim zweiten wird bei xor einfach nur edx nach eax kopiert (unterste 31 bit verschieden), wenn ich nun edx von eax subtrahiere kommt doch 0 raus wo hab ich da jetzt grade den denkfehler? Gruß Frank |
Re: Vorzeichen entfernen
Also, ganz langsam:
Bei allen vorzeichenbehafteten Typen gilt die Regel -x=not x + 1. Jedenfalls bei allen auf x86-Prozessoren, und ich vermute mal, bei so ziemlich allen anderen verbreiteten Binärprozessoren auch, weil so ziemlich alle das Zweierkomplement verwenden. cdq eax schreibt das Vorzeichenbit von eax in alle Bits von edx. cdq steht für "Convert to quad word", es führt also praktisch eine Umwandlung eines 32-Bit-Integers in einen Int64 durch. xor eax, edx macht im Fall edx=$00000000 gar nichts. eax bleibt also gleich, wenn es >=0 ist. xor eax, edx macht im Fall edx=$FFFFFFFF einfach ein "not eax", da jedes Bit auf 1 gesetzt wird, wenn es 0 ist und auf 0, wenn es 1 ist. sub eax, edx macht im Fall edx=$00000000 wieder nichts, da eax-0=eax ist. sub eax, edx macht im Fall edx=$FFFFFFFF einfach "eax+1", da eax-(-1)=eax+1 ist. Also haben wir im Endeffekt eine "Entfernung" des Vorzeichens, und zwar ganz ohne Sprünge, die unser prozessorinternes Pipelining stören könnten. |
Re: Vorzeichen entfernen
Zitat:
-5 - -2 = -3 als Beispiel einer Subtraktion von negativen Zahlen |
Re: Vorzeichen entfernen
Zitat:
-5 - -12 = 7 |
Re: Vorzeichen entfernen
Zitat:
.oO(sollte das wohl das nächste Mal entsprechend kennzeichnen) Frank |
Re: Vorzeichen entfernen
Zitat:
-X + -Y = +Z sondern ich hab geschrieben - + - = + |
Re: Vorzeichen entfernen
Zitat:
X - -Y => X + Y <offtopic> kann man das "-" und "+"nicht fett darstellen? Hier wird das FETT ignoriert:
Code:
X [b]- -[/b]Y => X [b]+[/b] Y
|
Re: Vorzeichen entfernen
@Topic: Gehen tut auch:
Delphi-Quellcode:
oder
Zahl:=Zahl*Sign(Zahl);
Delphi-Quellcode:
[edit]
If Zahl<0 Then Zahl:=Zahl-2*Zahl;
oder:
Delphi-Quellcode:
ZahlStr:=IntToStr(Zahl);
ZahlStr:=Copy(ZahlStr,Succ(Pos('-',ZahlStr)),Length(ZahlStr)); Zahl:=IntToStr(ZahlStr); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 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