2010-12-30 7 views
0

Wie erstelle ich die folgende Methode?Ziel C: Creating Long Double verwendet die Dezimalmethode

  • Ich versucht modf zu verwenden (n, 1) oder MODF (n, 2), aber diejenigen, sowohl einen Fehler von „Rückübergabe des Arguments 2 von modf erzeugt Zeiger von Ganzzahl ohne gegossen.

Heres das Verfahren:

(BOOL) numberHasDecimal: (long double) n { 
    if (?????) // has decimal, like 16.300000 or 6453.353259 
     return YES; 
    else 
     return NO; // has no decimal, like 58.000000 or 9274.000000 
} 

Antwort

0
if (fabsl(fmodl(n, 1.0)) > 0.0) { 
    // Has a decimal. 
} else { 
    // Is an integer. 
} 

beachten Sie, dass Gleitkommazahlen intern gerundet sind in kontra-intuitive Art und Weise, so kann eine Zahl mit einem sehr kleinen Bruchkomponente haben und nach wie vor erscheinen integral, wenn sie durch fmodl() übergeben werden.

Beachten Sie auch, dass Apples Implementierung von Objective-C bei der Verarbeitung von long double-Werten fehlerhaft ist und bei der Verwendung schwer nachvollziehbare Fehler aufweisen kann.

+0

Wenn ich 369.000000 durch diese Methode setzen, sagt es, dass es eine Dezimalzahl hat, warum ist das so? – michaellindahl

+0

Möglicherweise einer dieser oben erwähnten "langen Doppel"/Obj-C-Konflikte. Was ist der Rückgabewert von 'fmodl (369.0, 1.0)'? –

+0

es gibt 0 zurück ... Ich glaube, ich muss lange Doppel verwenden, weil ich sicherstellen muss, dass mein Code bis zu 999999999 machen kann * 999999999 – michaellindahl

0

Eine andere Wahl, weiß nicht, welche zur Auswahl, aber wahrscheinlich nicht diese.

-(BOOL) numberHasDecimal: (long double) n { 
    NSMutableString *decimalTempString; 
    decimalTempString = [NSMutableString stringWithFormat: @"%Lf", n]; 

    // while last character of string = 0 delete last character (1232.10000) 
    while ([decimalTempString characterAtIndex:([decimalTempString length] -1)] == '0') { 
     NSRange range = {([decimalTempString length] -1), 1}; 
     [decimalTempString deleteCharactersInRange:range]; 
    } 
    // if last character is . then delete that too (1232.) 
    if ([decimalTempString characterAtIndex:([decimalTempString length] -1)] == '.') { 
     return NO; // has no decimal, like 58. or 9274. 
    } else { 
     return YES; // has decimal, like 16.3 or 6453.353259 
    } 
0
- (BOOL) numberHasDecimal:(long double)l { 
    return (floorl(l) != l); 
} 
+1

'roundl()' wird auf die nächste Ganzzahl gerundet, was zu falsch positiven Ergebnissen führen kann. Verwenden Sie stattdessen 'floorl()'. –

0

Wie andere Plakate angedeutet haben, könnte eine bessere Frage zu definieren, was bedeutet „nicht ein Dezimalteil mit“. (Ich wiederhole auch ihre Warnungen bei langen Doppeln.) Welche Definition richtig ist, hängt davon ab, was Sie erreichen wollen. Ich finde, dass "innerhalb 1e-6" oft eine gute Definition ist, aber es hängt von der Situation ab.

Für Ihre spezielle Frage, mögen Sie wahrscheinlich diese:

-(BOOL) numberHasDecimal: (double) n 
{ 
    double integerPart = 0.; 
    if (fabs(modf(n, &integerPart)) > 0.) // has decimal, like 16.300000 or 6453.353259 
     return YES; 
    else 
     return NO; // has no decimal, like 58.000000 or 9274.000000 
} 

Was ist hier los ist, dass die modf Funktion will den Bruchteil und speichert den ganzzahligen Teil der Zahl in einer anderen Doppel zurückzukehren, um die Adresse in die du hineingehst. Trotz seines Namens ist es nicht das Äquivalent von "x% y"; es ist wirklich mehr das Äquivalent von "Return x% 1.0, auch Speicherung (x - Stock (x)) in den bereitgestellten Zeiger" (zumindest für positive Zahlen, das ist.)

Sie können sich die zweite, Zeiger denken Parameter als eine Möglichkeit, mehr als einen Wert von einem einzelnen Funktionsaufruf zurückzugeben. Auch wenn es Ihnen egal ist, in diesem Fall über den ganzzahligen Teil, wird die Übergabe einer Adresse für modf zum Schreiben des ganzzahligen Teils den Compiler beruhigen und Ihnen das Ergebnis bringen, nach dem Sie suchen.

Verwandte Themen