2016-03-28 9 views
9

Gibt es eine Funktion, die in Swift +1 für positive Zahlen und -1 für negative zurückgibt?"sign" -Funktion in Swift

Ich sah durch die enorme-Datei, wenn Sie ich seinen Namen nicht kennen rechten Klick-> Definitionen auf eine typische Funktion, aber wenn es dort erscheint.

Ich tat dies:

(num < 0 ? -1 : 1) 

Aber ich hätte lieber eine eingebaute Funktion verwenden, wenn es eine - für sich selbst zu dokumentieren Gründen auf das Minimum.

+0

Was war interessant, dass ich * nicht * war verrückt zu werden, gibt es etwas nicht wirklich * genau * wie diese. Sehr überraschend. –

Antwort

3

W.r.t. integrierte Funktionen, ich glaube, die nächstgelegene Sie Foundation Methode ist die im Falle copysign(_: Double, _: Double) -> Double

let foo = -15.2 
let sign = copysign(1.0, foo) // -1.0 (Double) 

Natürlich benötigen eine Art Konvertierung Sie Double auf eine Reihe von Art sind nicht in Betrieb erhalten werden.

Ich sehe jedoch keinen Grund, warum nicht Ihre eigene Erweiterung zu Ihren Bedürfnissen, speziell für eine so einfache Funktion wie sign, wie sie nicht aufgebläht, z.

extension IntegerType { 
    func sign() -> Int { 
     return (self < 0 ? -1 : 1) 
    } 
    /* or, use signature: func sign() -> Self */ 
} 

extension FloatingPointType { 
    func sign() -> Int { 
     return (self < Self(0) ? -1 : 1) 
    } 
} 

(hier ergibt 1 auch für 0, wie im Beispiel in Ihrer Frage).


(Bearbeiten im Hinblick auf Ihren Kommentar unten)

Eine alternative Lösung für die oben wäre ein eigenes Protokoll mit einer Standardimplementierung von sign(), zu definieren, so dass alle Arten zu diesem Protokoll entsprechen hätte Zugang zu dieser sign() Methode.

protocol Signable { 
    init() 
    func <(lhs:Self, rhs:Self) -> Bool 
} 

extension Signable { 
    func sign() -> Int { 
     return (self < Self() ? -1 : 1) 
    } 
} 

/* extend signed integer types to Signable */ 
extension Int: Signable { } // already have < and init() functions, OK 
extension Int8 : Signable { } // ... 
extension Int16 : Signable { } 
extension Int32 : Signable { } 
extension Int64 : Signable { } 

/* extend floating point types to Signable */ 
extension Double : Signable { } 
extension Float : Signable { } 
extension CGFloat : Signable { } 

/* example usage */ 
let foo = -4.2 
let bar = 42 

foo.sign() // -1 (Int) 
bar.sign() // 1 (Int) 
+0

Ich denke, die Erweiterung ist letztlich der Weg zu gehen, bin ich völlig überrascht, dass so etwas noch nicht existiert! Gibt es überhaupt eine Möglichkeit, Generika dafür zu nutzen? Oder sind die numerischen Typen Teil dieser "Cluster", die nicht wirklich generisch sind? –

+0

@MauryMarkowitz Selbst ein benutzerdefiniertes globales 'Zeichen (arg: T)' müsste eine Typbeschränkung für ein Protokoll enthalten, das die weniger als Funktion '<' sowie die Initialisierung für den Wert von ' als "Null" betrachten. Außerdem müssten wir alle Typen, die wir verwenden möchten, auf dieses Protokoll erweitern, was einige Codes für alle Swift-Typen bedeuten würde. In diesem Fall ist die Verwendung einer Erweiterung für "IntegerType" und "FloatingPointType" (wie oben) eine weniger schmerzhafte Option. Ich werde jedoch ein Beispiel mit dem Ansatz einbeziehen. – dfri

4

Verwendung:

let result = signbit(number) 

Dies gibt 1 zurück für negative Zahlen und 0 für positive Ergebnisse.

let number = -1.0 
print("\(signbit(number))") 

1 

let number = 1.0 
print("\(signbit(number))") 

0 
+0

würde dies 0 oder 1 zurückgeben würde es nicht? –

+0

ja, 1 für negative, 0 für positive – Masih

+0

Beachten Sie, dass dies das Vorzeichenbit für Zahlen verwendet, die durch das Gleitkomma-Muster dargestellt werden, und daher nur für Gleitkommatypen funktioniert. Um das Vorzeichen von say einer Ganzzahl zu testen, müssten Sie vor der Anwendung dieser Methode zuerst auf "Double" umwandeln. – dfri

1

FloatingPointType hat eine eingebaute berechnete Variable, aber es gibt einen booleschen Wert zurück. Wenn Sie nur diesen Vorgang auf Schwimmern benötigen, können Sie eine Erweiterung wie folgt verwenden:

extension FloatingPointType { 
    var signValue: Int { 
     return isSignMinus ? -1 : 1 
    } 
} 

Aber ich glaube, der beste Ansatz, um die SignedNumberType Protokoll zu erweitern wäre.

extension SignedNumberType { 
    var signValue: Int { 
     return (self >= -self) ? 1 : -1 
    } 
} 

Wenn Sie 0 zurückkehren wollen -1 dann nur >=-> ändern.

Testfälle:

print(3.0.signValue) 
print(0.signValue) 
print(-3.0.signValue) 
+0

'0.signValue' sollte wahrscheinlich' 0' zurückgeben – Clashsoft

+1

Ziemlich wahrscheinlich, obwohl ich denke, es hängt von Ihrem spezifischen Anwendungsfall ab. Ich implementierte das Verhalten in Übereinstimmung mit seinem oben gezeigten Beispiel. – Kevin

1

Da copysign nicht über Integer verwendet werden, kann ich diese Erweiterung bin mit:

extension Comparable where Self: SignedNumber { 

    var sign: Int { 
     guard self != -self else { 
      return 0 
     } 
     return self > -self ? 1 : -1 
    } 
} 
3

Die simd Bibliothek ein Zeichen Methode hat:

import simd 

sign(-100.0) // returns -1 
sign(100.0) // returns 1 
sign(0.0) // returns 0 

Sie erhalten simd kostenlos, wenn Sie import SpriteKit.

4

In Swift-4 Schwimmern eine neue Eigenschaft haben:

public var sign: FloatingPointSign { get } 
+0

yay! scheint wie ein Kinderspiel ... –

+0

wir Herz Swift4 – Fattie