Frage

Ich habe diese Methode

+ (CGFloat) round: (CGFloat)f {
    int a = f;
    CGFloat b = a;
    return b;
}

Es funktioniert wie erwartet, aber es rundet nur nach unten. Und wenn es eine negative Zahl ist immer noch abrundet.

Dies war nur eine schnelle Methode, die ich gemacht, es ist nicht sehr wichtig ist, dass es richtig rundet, ich habe es nur aus der Kamera x und y-Wert für mein Spiel runden.

Ist diese Methode in Ordnung? Ist es schnell? Oder gibt es eine bessere Lösung?

War es hilfreich?

Lösung

Es gibt bereits Standardfunktionen mit Verhaltensweisen, die Sie in <math.h> benötigen wie: floorf, ceilf, roundf, rintf und nearbyintf (LaSF 'f' bedeutet "float" Version, Versionen ohne sie sind "doppelte" Versionen).

Es ist besser, Standardverfahren zu verwenden, nicht nur weil sie Standard sind, sondern weil sie besser funktionieren in Grenzfällen.

2013 Update (jessedc)

iOS ist nicht mehr nur 32 Bit. Es gibt eine Reihe von anderen Antworten auf diese Frage, die jetzt mehr relevant ist.

Die meisten Antworten erwähnen Import tgmath.h

Andere Tipps

2018 Antwort

Die anderen Antworten hier sind entweder veraltet oder nicht geben gute Beispiele. Es ist leicht, ein CGFloat mit Swift in rounded Funktion gebaut abzurunden.

let x: CGFloat = 3.5
let y = x.rounded() // 4.0

Wenn Sie den Wert anstelle abrunden möchten, können Sie round verwenden:

var x: CGFloat = 3.5
x.round() // 4.0

Rundungsregeln

Wenn Sie eine genauere Kontrolle über wollen, wie Zahlen gerundet sind, können Sie ein verwenden FloatingPointRoundingRule .

weg von Null

x.rounded(.awayFromZero)

Die Zahlen über Null sind gerundet und Zahlen unter Null sind abgerundet.

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

unten

x.rounded(.down)

Runden eine beliebige Zahl mit einem Dezimalwert nach unten auf die nächstkleinere ganze Zahl. Dies ist die gleiche wie floor(x).

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

Zum nächsten oder weg von Null

x.rounded(.toNearestOrAwayFromZero)   // same as x.rounded()

Dezimalzahlen erhalten auf die nächste ganze Zahl abgerundet. Wenn jedoch der Wert genau in der Mitte ist (wie 3.5 oder -3.5) dann positive Zahlen erhalten aufzurunden und negative Zahlen abgerundet bekommen.

Es kann eine lange komplizierte Namen, aber dies in der Regel ist, wie man lernt in der Schule Rundung. Es ist auch die Regel verwendet, wenn Sie nur x.rounded() tun.

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0  ***
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0  ***
-3.999  ->  -4.0

Zum nächsten oder sogar

x.rounded(.toNearestOrEven)

Dies ist ähnlich toNearestOrAwayFromZero, es sei denn jetzt die .5 Werte an die auch ganze Zahl gerundet erhalten.

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0   ***
3.999  ->  4.0
4.500  ->  4.0   ***

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0   ***
-3.999  ->  -4.0
-4.500  ->  -4.0   ***

gegen Null

x.rounded(.towardZero)

Das hat nur die Wirkung des Schneidens keine Dezimalzahlen aus. Wenn Sie eine Int benötigt man die gleiche Sache mit Int(x) tun könnte.

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

Up

x.rounded(.up)

Das ist das Gegenteil von .down. Alle Dezimalzahlen sind gerundet. Dies ist die gleiche wie ceil(x).

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

Notizen

  • Vergessen Sie nicht, negative Werte zu berücksichtigen.
  • Die Ergebnisse der round und rounded sind noch CGFloat. Wenn Sie eine Int benötigen, müssen Sie es wie Int(myCGFloat) konvertieren.
  • Es gibt keine Notwendigkeit, die C mathematische Funktionen round(x), ceil(x) und floor(x) mehr zu verwenden. Allerdings, wenn Sie sie verwenden, laden sie beide 64 und 32-Bit-Architektur behandeln, so irgendwelche Antworten, die Sie mit roundf, ceilf und floorf gesehen haben können, sind jetzt veraltet.

A CGFloat heißt typedef'd entweder ein double oder ein float, so dass Sie sie wie jede andere echte Art runden können:

CGFloat round(CGFloat aFloat)
{
    return (int)(aFloat + 0.5);
}

Beachten Sie, dass während dieser Arbeiten mit klein genug, um Schwimmern einen Bruchteil zu tragen, es auf große Werte seltsam wirken.

Versuchen #import "tgmath.h".

Der <tgmath.h> Header wird die Header <math.h> und <complex.h> umfasst und mehrere Typen-generic-Makros definieren.

Sie sind das Rad neu erfinden - und dies ist eine C Frage, nicht Objective C. Verwenden Sie einfach die Standard-C-Funktion round ()

.

Für 32 und 64 Arbeitsbitregister Sie Ihre eigenen Makros wie

erstellen
#ifndef CGFLOAT_CEIL
    #ifdef CGFLOAT_IS_DOUBLE
        #define CGFLOAT_CEIL(value) ceil(value)
    #else
        #define CGFLOAT_CEIL(value) ceilf(value)
    #endif
#endif

Ps dies ist keine Antwort auf die Frage, sondern eine Ergänzung für die Frage, wie man die Arbeit mit 32/64 Bit-Werten.

Definieren Sie diese in einer Datei wie MyMacros.h und als einen Import in der myapp-Prefix.pch

hinzufügen

Denken Sie auch daran, dass für die Funktion CGFloat als Präfix wählen kann ein Risiko sein, da Apple ein Makro wie folgt hinzufügen könnte sie selbst damit ist, warum die #ifndef CGFLOAT_CEIL heißt

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top