Domanda

Come si crea il seguente metodo?

  • Ho cercato di uso modf (n, 1) o modf (n, 2) ma quelli entrambi tornare un errore di "Passaggio argomento 2 di modf rende puntatore dalla intero senza un cast.

Ecco il metodo:

(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
}
È stato utile?

Soluzione

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

tenere presente che i valori virgola mobile sono arrotondati internamente in modo intuitivo, per cui un numero può avere una piccola componente frazionaria e ancora apparire integrale quando passa attraverso fmodl().

Si noti inoltre che l'attuazione di Apple di Objective-C è rotto durante la manipolazione dei valori long double, e può manifestarsi errori difficili da pista quando li si utilizza.

Altri suggerimenti

Un'altra scelta, non so quale scegliere, ma probabilmente non questo.

-(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
    }

Come altri utenti hanno indicato, una domanda migliore potrebbe essere quella di definire ciò che "non avere una parte decimale" si intende. (Inoltre, mi associo le loro precauzioni su lunghi doppie.) Quale definizione è giusta dipende da ciò che si sta cercando di raggiungere. Trovo che "entro 1e-6" è spesso una definizione buona, ma dipende dalla situazione.

Per la vostra domanda specifica, probabilmente si vuole in questo modo:

-(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
}

Cosa sta succedendo è che la funzione modf vuole restituire la parte frazionaria e memorizzare la parte intera del numero in un altro doppio, il cui indirizzo si passa in esso. Nonostante il suo nome, non è l'equivalente di "x% y"; è davvero più l'equivalente di "ritorno x 1,0%, anche memorizzare (x - piano (x)) nel puntatore fornito" (almeno per numeri positivi, che è.)

E 'possibile pensare al secondo, parametro di puntatore come un modo per restituire più di un valore da una singola chiamata di funzione. Anche se non si cura, in questo caso, la parte intera, passando domicilio modf a scrivere la parte intera nella calmerà il compilatore e si ottiene il risultato che stai cercando.

- (BOOL) numberHasDecimal:(long double)l {
  return (floorl(l) != l);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top