Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Vorzeichen entfernen (https://www.delphipraxis.net/98607-vorzeichen-entfernen.html)

3_of_8 29. Aug 2007 22:08

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:
if x<0 then x:=not x + 1;
Oder, der schnellere Assembler-Weg:
Code:
cdq eax
xor eax, edx
sub eax, edx

Dax 29. Aug 2007 22:08

Re: Vorzeichen entfernen
 
Zitat:

Zitat von _frank_
ein etwas exotischer weg wäre sicher auch, das höchstwertige Bit auf 0 zu setzen :)

Und vor allem eine so schöne, schwer entdeckbare Fehlerquelle... -1 = 0xFFFFFFFF, nach dir gälte dann 1 = 0x7FFFFFFF.

_frank_ 29. Aug 2007 22:43

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:
if x<0 then x:=not x + 1;
immer? also bei allen signed datentypen?

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:
edx      eax
$FFFFFFFF $FFFFFFFF
bzw.
Code:
$00000000 $7FFFFFFF
xor setzt dann bei ersterem eax auf $0, da eax=edx.
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

3_of_8 29. Aug 2007 23:48

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.

raiguen 31. Aug 2007 10:28

Re: Vorzeichen entfernen
 
Zitat:

Zitat von _frank_
Zitat:

Zitat von SirThornberry
(denn - + - ergibt +)

achso? wusste ich noch gar nicht :)

kannte das nur als
- * - = +

da würde ja
-5 + -2

+7 ergeben, richtig? oder vielleicht +3... :gruebel:

Ähm... :roll: wenn mich meine bescheidenen Mathekenntnisse nicht täuschen, dann ergibt die Addition von negativen Zahlen immer noch eine negative Zahl, sprich in diesem Beispiel käme dann -7 heraus :lol:

-5 - -2 = -3 als Beispiel einer Subtraktion von negativen Zahlen

RavenIV 31. Aug 2007 10:32

Re: Vorzeichen entfernen
 
Zitat:

Zitat von raiguen
Ähm... Rolling Eyes wenn mich meine bescheidenen Mathekenntnisse nicht täuschen, dann ergibt die Addition von negativen Zahlen immer noch eine negative Zahl, sprich in diesem Beispiel käme dann -7 heraus Laughing

Muss nicht immer stimmen:
-5 - -12 = 7

_frank_ 31. Aug 2007 10:43

Re: Vorzeichen entfernen
 
Zitat:

Zitat von raiguen
Ähm... :roll: wenn mich meine bescheidenen Mathekenntnisse nicht täuschen, dann ergibt die Addition von negativen Zahlen immer noch eine negative Zahl, sprich in diesem Beispiel käme dann -7 heraus :lol:

-5 - -2 = -3 als Beispiel einer Subtraktion von negativen Zahlen

da hat jemand die Ironie meines Beitrages nicht verstanden...

.oO(sollte das wohl das nächste Mal entsprechend kennzeichnen)

Frank

SirThornberry 31. Aug 2007 10:49

Re: Vorzeichen entfernen
 
Zitat:

Zitat von _frank_
Zitat:

Zitat von SirThornberry
(denn - + - ergibt +)

achso? wusste ich noch gar nicht :)

kannte das nur als
- * - = +

da würde ja
-5 + -2

+7 ergeben, richtig? oder vielleicht +3... :gruebel:

das minus voranstellen macht ja auch ne multiplikation
sicher nur ein schreibfehler, aber wollte das nicht so stehen lassen...

ein etwas exotischer weg wäre sicher auch, das höchstwertige Bit auf 0 zu setzen :)

Gruß Frank

ich hab nicht geschrieben
-X + -Y = +Z
sondern ich hab geschrieben
- + - = +

RavenIV 31. Aug 2007 10:54

Re: Vorzeichen entfernen
 
Zitat:

Zitat von SirThornberry
ich hab nicht geschrieben
-X + -Y = +Z
sondern ich hab geschrieben
- + - = +

Also meinst Du:

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

Sidorion 31. Aug 2007 11:06

Re: Vorzeichen entfernen
 
@Topic: Gehen tut auch:
Delphi-Quellcode:
Zahl:=Zahl*Sign(Zahl);
oder
Delphi-Quellcode:
If Zahl<0 Then Zahl:=Zahl-2*Zahl;
[edit]
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.
Seite 2 von 3     12 3      

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