2009-06-10 12 views
31

Ich bekomme Fehler in meinem iPhone Programmierung, wenn ich versuche, Pi zu verwenden. Ich versuchePi in Objective C

float pNumber = 100*cos(2 * pi * (days/23)); 

Aber ich Fehler erhalten, die sagen:

_pi, verwiesen von

_pi $ non_lazy_ptr

ich im Internet irgendwo sah M_PI zu verwenden und es kompiliert aber Ich glaube nicht, dass es mir die richtige Berechnung gibt.

Wenn ich versuche:

float pNumber = 100*cos(2 * M_PI * (15746/23)); 

I 0

Dank

+0

Zuerst würde ich meine Konstanten floats. – Nosredna

Antwort

55
  • Die Integer-Division erhalten wahrscheinlich in einen Floating-Point ein (Guss eine der Zahlen auf ein dazu gezwungen werden muss, doppelt - oder verwenden Sie die Notation 23.0, um anzugeben, dass Sie eine Gleitkommadivision wünschen.
  • Versuchen Sie, M_PI auszudrucken und zu sehen, was es sagt (printf("M_PI = %16.9g\n", M_PI); in C).
  • Haben Sie die Deklaration für cos() aufgenommen? Wenn nicht, kann es als eine Funktion interpretiert werden, die eine Ganzzahl (#include <math.h> vielleicht) zurückgibt.

Beispiel Code (in C auf 10 SPARC Solaris mit GCC getestet 4.3.3):

#include <math.h> 
#include <stdio.h> 

int main(void) 
{ 
    float pNumber = 100*cos(2 * M_PI * (15746/23)); 
    printf("M_PI = %16.9g\n", M_PI); 
    printf("pNum = %16.9g\n", pNumber); 
    pNumber = 100*cos(2 * M_PI * (15746/23.0)); 
    printf("pNum = %16.9g\n", pNumber); 
    return 0; 
} 

Beispiel Ausgang:

M_PI =  3.14159265 
pNum =    100 
pNum =  -77.5711288 
+0

Wie wirfst du einen Int in einen Float in Ziel C? – Xcoder

+2

Objective-C ist eine perfekte (ich denke) Supermenge von C, also können Sie es genauso machen wie in C. – Nosredna

+0

Ich habe das versucht Tage = (float) Tage; float pNumber = 100 * cos (2 * pi * (Tage/23)); Immer noch nicht funktioniert. Ich bekomme 0. Das ist, was ich tun werde: http://StackOverflow.com/Questions/975959/generate-a-periodic-value-based-on-dates – Xcoder

4

C/C++ und Objective C somit/C++ fördert Integer nicht zum Floaten bei normaler Division.

Also in C/C++ bewertet der Ausdruck 15746/23 zu 567, nicht zu 567.71207, wie Sie naiv erwarten könnten.

C werden ganze Zahlen zu fördern wie nötig schwimmt, wenn eine oder andere Operand ein Schwimmer ist, so alles, was Sie brauchen, ist 15.746,0 oder 23,0 in Ihrem Ausdruck tun verwenden, dh Änderung

float pNumber = 100*cos(2 * M_PI * (15746/23.0)); 

Die 100 wird automatisch befördert werden, weil cos einen Float zurückgibt (eigentlich ein Double, aber ich ignoriere Float/Double Percussion-Probleme). Die 2 wird zu einem Gleitkomma befördert, weil M_PI ein Gleitkomma ist. Und die 15746 wird zu einem Gleitkomma befördert, weil 23.0 ein Gleitkomma ist.

Allerdings würde es nicht schaden, die 0,0 an alle Konstanten hinzufügen, das heißt:

float pNumber = 100.0*cos(2.0 * M_PI * (15746.0/23.0)); 
+0

Danke für den tollen Vorschlag Peter aber ich mache immer noch etwas falsch. Ich versuche, eine Nummer zwischen 0 und 100 zu bekommen. Hier ist der Deal, 15746 ist die Anzahl der Tage seit einem Geburtstag. Alle 23 Tage möchte ich eine Spitze von 100. Wenn Sie 12 teilen, sollten Sie "Tal" erhalten, das gleich 0 ist. So möchte ich in der Lage sein, die Anzahl der Tage eines beliebigen Tages zu erhalten und zu sehen, um welche Zahl es sich handelt 1 und Null basierend auf alle 23 Tage.Diese Formel wurde von zwei Leuten empfohlen, aber ich bekomme die Nummer 15746. Irgendwelche Vorschläge? – Xcoder

+0

@Robb Wie wäre es, wenn Sie uns das ganze Programm zeigen? Wir sehen hier und da nur eine Linie. Gib uns das kleinste Programm, das das tut, was du sagst. Und sagen Sie uns, was Ihr C-Compiler ist und welches Betriebssystem Sie ausführen. – Nosredna

+0

Robb, cos gibt ein Ergebnis mit einem Bereich von -1,0 bis 1,0 zurück, und Sie multiplizieren dann mit 100,0, sodass das Ergebnis einen Bereich von -100,0 bis 100,0 haben muss. So kann ich nicht sehen, wie Sie 15746 bekommen können. Tatsächlich wird das oben genannte -77.571128 erzeugen. Sie müssen mehr Code, vorzugsweise eine vollständige Beispielfunktion, posten. –

1

Das Problem ist die Integer-Division im innersten Teil des Ausdrucks, die den Wert abschneidet (Weglassen der Bruchteil). Wie bereits erwähnt, besteht eine Möglichkeit darin, jede Konstante zu einer Gleitkommazahl zu machen, indem man entweder ".0" oder "f" hinzufügt. Alternativ können Sie die Klammern vom innersten Ausdruck vollständig weglassen.Da M_PI eine Gleitkommazahl ist und die Multiplikation in C linksassoziativ ist (was bedeutet, dass sie von links nach rechts verläuft), wird die erste Multiplikation (2 * M_PI) zu einer Gleitkommazahl hochgestuft, ebenso wie jede nachfolgende Multiplikation. Da cos() einen Gleitkommawert zurückgibt, wird pNumber ein Gleitkomma zugewiesen, ohne dass eine Ganzzahldivision ausgeführt wurde, daher kein Genauigkeitsverlust. (Hinweis: Es ist normalerweise nicht ratsam, Assoziativität oder Vorrang des Bedieners zu berücksichtigen, aber in diesem Fall versuche ich nur zu demonstrieren, dass es tatsächlich funktionieren würde.)

So weit der Zahlenbereich, den Sie erwarten sollten , erinnern Sie sich, dass der Kosinus (unmodifiziert) von -1 bis +1 reicht, nicht 0 bis 1, also würden Sie theoretisch -100 bis 100 (in der Theorie) sehen. Um den richtigen Bereich zu erhalten, möchten Sie 1 hinzufügen und dann mit 50 multiplizieren.

Übrigens sind die Kompilierungsfehler, die Sie im ersten Fall erhalten, weil pi nicht definiert ist. Die Anleitung zur Verwendung von M_PI ist korrekt - für mathematische Konstanten ist es immer schlauer (und konsistenter), das zu verwenden, was das System bietet. Wenn Sie neugierig sind, sind diese Konstanten auf Leopard in Math.h, Zeilen 528-540, definiert. Sie können die Datei öffnen, indem Sie Datei> Schnell öffnen ... (Cmd-Shift-D) verwenden und "Math.h" eingeben, oder doppelklicken Sie in Ihrem Code auf M_PI, während Sie Command gedrückt halten.

+0

Wie viel Präzision wird benötigt? .. Was ist die M_PI Konstante definiert als? .. Was würde 355/113 auswerten? –

0

Warum eine Sinuskurve an erster Stelle verwenden?

Wenn das Ziel eine fonction von 0 bis 100 reich haben, ist dann 100-0 in 23 Tagen können Sie verwenden:

// x ranges from 0 to 2 
float x = (days % 23)/11.5; 
// pNumber is a saw ranging from 0 to 100 
float pNumber = 100 * abs(x - 1); 

Sie können auch die x durch eine Cosinus ersetzen, wenn Sie wirklich eine wünschen , als 2 * pi/23 ~ = 0,273, haben Sie

float x = 1 + cos((days % 23)*0.273);