![]() |
Function für Vorzeichen?
Hi!
Gibt's ne Funktion, der man einen Real übergibt und die dann 1 zurückgibt, wenn die Zahl positiv ist, und -1, wenn sie negativ ist? Dass man einfach schreiben kann
Delphi-Quellcode:
Bisher mach ich das so:
a := Vorzeichen(b)*5;
Delphi-Quellcode:
Aber das ist sicherlich nicht die eleganteste Art.
a := Abs(b)/b*5;
|
Re: Function für Vorzeichen?
Dafür gibts die Funktion
![]() |
Re: Function für Vorzeichen?
Delphi-Quellcode:
function IsPositive(Value: Integer): Boolean;
begin result := Value > 0; end; |
Re: Function für Vorzeichen?
@ 3_of_8:
Kann es sein, dass es sign auf delphi 5 noch nicht gibt? @ Luckie: Ich brauch nicht ne Funktion, die mir sagt, ob die Zahl positiv ist, sondern eine, die mir das Vorzeichen zurückliefert (also 1 oder -1). Sonst könnte ich ja auch ne If-Abfrage machen. |
Re: Function für Vorzeichen?
Wenns ein einfacher Term sein soll:
Delphi-Quellcode:
Im Fall einfach in eine Funktion schmeissen ;)
ord(value >= 0) * 2 - 1
greetz Mike [Edit] >= statt > , dann gehts auch mit 0... |
Re: Function für Vorzeichen?
Einfach Math importieren.
@Jason: Das geht nicht, wenn du ne 0 reinbekommst. |
Re: Function für Vorzeichen?
also ich weiß nicht, was du hast?
Delphi-Quellcode:
[add]
If X >= 0 Then Positiv Else Negativ;
PS: das sagt mein Delphi :zwinker:
Delphi-Quellcode:
// Unit Math
function Sign(const AValue: Integer): TValueSign; begin Result := ZeroValue; if AValue < 0 then Result := NegativeValue else if AValue > 0 then Result := PositiveValue; end; |
Re: Function für Vorzeichen?
Ich hätt das jetzt so gelöst:
Delphi-Quellcode:
function Sign(const AValue: Integer): Integer;
asm cmp eax, 0 ja @positive cdq mov eax, edx ret @positive: mov eax, 1 end; |
Re: Function für Vorzeichen?
Delphi-Quellcode:
function Vorzeichen(Value: Integer): Char;
begin result:='+'; if (Value < 0) then result:='-'; end; |
Re: Function für Vorzeichen?
So hat er das nicht gemeint. Er wollte eine Integer-Wert. Außerdem hast du eine unnötige Zuweisung drin und die 0 hat kein Vorzeichen, auch kein positives. ;)
|
Re: Function für Vorzeichen?
Zitat:
Delphi-Quellcode:
Gruß Jürgen
function Vorzeichen( const dValue: double ): integer;
begin if dValue >= 0 then begin if dValue = 0 then Result := 0 else Result := 1; end else Result := -1; end; |
Re: Function für Vorzeichen?
Dann kann ich's eigentlich auch mit Abs(Value)/Value machen. Ich dachte, da gäb's vielleicht ne fertige Funktion für, aber die selber zu schreiben (sign kennt mein delphi nicht) führt ja nur zu zusätzlichen Codezeilen. Oder hat meine Variante irgendwelche nachteile? (wenn Value 0 ist, wird der Code sowieso nicht aufgerufen, es würde also nicht durch 0 geteilt)
|
Re: Function für Vorzeichen?
Zitat:
Zitat:
|
Re: Function für Vorzeichen?
Also gut, jetzt noch einmal. Sign steht in der Unit Math. Die einbinden. Das dürfte auch bei Delphi 4 oder was du hast drinsein.
Und außerdem habe ich dir schon einen Code geschrieben, der mit EINER If-Abfrage auskommt. abs(value)/value ist ineffizient, wenn dann schon abs(value) div value, was bei einer 0 versagt, weil man nunmal nicht durch 0 teilen kann. Außerdem ist so ein div im Vergleich zu meinem Code wirklich langsam. Zitat:
|
Re: Function für Vorzeichen?
Hallo,
hier ist noch eine Assembler-Version:
Delphi-Quellcode:
Die folgenden PASCAL-Versionen haben den Vorteil, daß man sie im BDS mit der INLINE-Direktive versehen kann. In zeitkritischen Routinen kann man damit einen zusätzlichen Geschwindigkeitsvorteil erzielen:
function Sign2 (aValue: Integer): Integer;
asm sar eax,31 or eax,1 end;
Delphi-Quellcode:
Gruß Hawkeye
function SignInt (aValue: Integer): Integer; {nur für BDS: inline;}
const cSign: array [Boolean] of Integer = (-1, +1); begin Result := cSign[aValue >= 0]; end; function SignFloat (aValue: Double): Integer; {nur für BDS: inline;} const cSign: array [Boolean] of Integer = (-1, +1); begin Result := cSign[aValue >= 0]; end; |
Re: Function für Vorzeichen?
Das funktioniert so nicht ganz.
Denn bei 0 hast du eine 0 im Sign-Bit und dann kriegst du bei einer 0 als Result 1. Und wenn du das willst, geht das auch genausogut so: |
Re: Function für Vorzeichen?
Hallo Manuel,
Zitat:
PS: In deiner Assembler-Routine solltest du das "JA" durch ein "JG" ersetzen. :wink: Gruß Hawkeye |
Re: Function für Vorzeichen?
Zitat:
Zitat:
Zitat:
Zitat:
Ich hab mir nach euren Tipps jetzt doch ne Function gebastelt:
Delphi-Quellcode:
function Sign(Value: Real): Integer;
begin If Value < 0 then result := -1 else result := 1; end; |
Re: Function für Vorzeichen?
Aber eigentlich sollte D5 Sign kennen (siehe Unit Math)
PS: @Threadersteller rate mal, was deine Variante mit der Divition sagt, wenn man der eine 0 gibt :warn: |
Re: Function für Vorzeichen?
Er sagte, es kommt nie dazu.
Und @Cöster: Nimm nie ein if, wenn du stattdessen eine arithmethische Operation kriegst. Ifs bremsen den Prozessor ab. |
Re: Function für Vorzeichen?
Zitat:
Die Version von Hawkeye219 ist laufzeittechnisch schon optimal - schade dass man Assembler-Funktionen nicht inline machen kann... // Nachtrag: ich Dummkopf...
Delphi-Quellcode:
function Sign(Value: Integer): Integer; inline;
begin Result := (Value shr 31) or 1; end; |
Re: Function für Vorzeichen?
Zitat:
Kann es vielleicht sein, dass die Unit Math für spätere Delphi-Versionen überarbeitet wurde? Übrigens: TryIntToStr kennt Delphi 5 Standard auch nicht. Zitat:
|
Re: Function für Vorzeichen?
@Flocke
SHR ist in Delphi ein vorzeichenloser Shift nach rechts - unabhängig von der Art des Operanden. Das Gegenstück (ASR) haben die Borländer leider nicht implementiert. @Cöster: Die Unit Math wurde/wird ständig erweitert, die Sign-Funktionen wurden in Delphi 6 hinzugefügt. Eine Erklärung zu Manuels Aussage findest du in der ![]() Gruß Hawkeye |
Re: Function für Vorzeichen?
Zitat:
Zitat:
|
Re: Function für Vorzeichen?
@Flocke: Das weiß ich. Aber ich verwende nur ein if anstatt von zwei, was das ganze wieder beschleuningt.
|
Re: Function für Vorzeichen?
Zitat:
|
Re: Function für Vorzeichen?
Zitat:
edit: :wall: Ja, ich hab mir das shr als sar vorgestellt beim lesen, aber warum das or muss, ist mir erst später aufgefallen... Nennt mich nicht blöd, bindet mir ein Schild um :| |
Re: Function für Vorzeichen?
Zitat:
(if then else) |
Re: Function für Vorzeichen?
Ganz einfach: Wenn er eine 0 oder eine 1 reinkriegt, hat er eine 0 als Ergebnis. Das muss aber eine 1 sein, darum or 1.
@Cöster: Eigentlich hätte ich schreiben sollen eine logisch-arithmetische Operation. Dazu gehören +-*/, div und mod und außerdem not, and, or, xor, shl, shr, sar und vllt hab ich noch welche Vergessen. Auf Assemblerebene gibts noch ein paar zusätzliche wie z.B. cdq, was allerdings eher ein Cast zu einem Int64 ist. Diese Operationen bremsen im Gegenteil zu einem if den Prozessor nicht ab. (Pipelining) Das ist auch der Grund, warum z.B. die Funktion abs nicht mithilfe von Ifs implementiert ist, sondern mit einem cdq und einem xor. Noch ein Beispiel: Du willst eine Variable zwischen 0 und 1 umschalten, also wenn a=0 dann a:=1 ansonsten a:=0; Das könnte man jetzt so machen: if a=0 then a:=1 else a:=0; Man könnte es aber auch so machen: a:=1-a; Zweiteres geht deutlich schneller. Zu deinem einen If: 1. lässt sich das auch noch vermeiden und 2. bekommst du mit deiner Funktion NICHT das Vorzeichen. |
Re: Function für Vorzeichen?
Zitat:
Zitat:
a := sign(b)*a; Wie lässt sich das if denn in der Funktion verhindern (ohne Assembler-Code)? Mehr als result := value/abs(value) fällt mir nicht ein. Aber das soll ja noch langsamer sein, als ein if. Wie kann man das denn ohne if (und ohne Assembler) schreiben? :gruebel: |
Re: Function für Vorzeichen?
Zitat:
|
Re: Function für Vorzeichen?
Zitat:
Delphi-Quellcode:
function Sign(i: Integer): Integer;
begin Result := (0 - (i shr 31)) or 1; end; |
Re: Function für Vorzeichen?
Hallo Cöster!
Zitat:
Zitat:
@Dax: so geht's :thumb: Gruß Hawkeye |
Re: Function für Vorzeichen?
Sondern? Natürlich, ich bekomme nicht - oder +, aber -1 oder +1. Das ist auch alles, was ich will. Ich brauch den Befehl "hänge an a das Vorzeichen von b dran" und dafür schreib ich dann
a := sign(b)*a; Wie lässt sich das if denn in der Funktion verhindern (ohne Assembler-Code)? Mehr als result := value/abs(value) fällt mir nicht ein. Aber das soll ja noch langsamer sein, als ein if. Wie kann man das denn ohne if (und ohne Assembler) schreiben? :gruebel:[/quote] Du bekommst bei einer 0 eine +1 raus. Eine 0 hat aber kein Vorzeichen, folgerichtig muss also bei einer 0 eine 0 rauskommen. Das geht natürlich dann nicht ohne if, aber mit einem statt 2. |
Re: Function für Vorzeichen?
Moin Zusammen,
ist ja schön, dass ihr so viele Vorschläge macht, wie man das bei integer-Werten machen kann, Cöster sucht das aber für Real ;-) |
Re: Function für Vorzeichen?
Er kann ihn ja vorher truncaten.
|
Re: Function für Vorzeichen?
Moin Manuel,
das dürfte nicht viel helfen, wenn der Wert zwischen -1 und +1 liegt. |
Re: Function für Vorzeichen?
Zitat:
Delphi-Quellcode:
function Sign(e: Extended): Integer;
begin Result := (0 - (e shr 79)) or 1; end; |
Re: Function für Vorzeichen?
Dax, diesmal muß ich dich enttäuschen - SHR erwartet einen ganzzahligen Operanden.
Zitat:
Zitat:
|
Re: Function für Vorzeichen?
Zitat:
Gings denn so?
Delphi-Quellcode:
function Sign(e: Extended): Integer;
type PExtendedRec = ^TExtendedRec; TExtendedRec = record case Integer of 0: (e: Extended); 1: (a: Array[0..9] of Byte); end; begin Result := (0 - (PExtendedRec(@e)^.a[0] shr 7)) or 1; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:47 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