2013-01-05 20 views
8

Powiel możliwe:
NaN Literal in C?Jak zdefiniować wartość NaN w ANSI C?

Piszę funkcję w ANSI C, który otrzymuje dwa numery jako parametry. Parametry są typu int lub float. Ta liczba może być ważna lub nie, zgodnie z moim filtrem. Jak mogę zwrócić pewną wartość oznaczającą niepowodzenie? Typ zwrotu to float. Pierwszą rzeczą, która przyszła mi na myśl, był abstrakcyjny typ NaN. Ale nie wiem, jak do reprezentowania go w ANSI C

(przepraszam za mój zły język angielski. Angielski nie jest mój język ojczysty)

+0

@OliCharlesworth: Ale to C99 – Jack

+0

Jedna z odpowiedzi sugerowała "0.0/0.0". –

+1

Nie ma absolutnie przenośnej drogi, NaN nie istnieje w C89 i nie jest obowiązkowe od C99. – effeffe

Odpowiedz

12

NaN nie jest "typem abstrakcyjnym". Jest to wartość punktu odniesienia zmiennoprzecinkowego.

Jeśli przez „ANSI C” masz na myśli standardową C (co jest rzeczywiste znaczenie terminu, w jak to ma), to <math.h> i użyć NAN makro do wytworzenia Nan i isnan(x) wykryć jedną .

Jeśli przez „ANSI C” faktycznie oznacza, długo zastąpione standardu C89 (który niektórzy ludzie zamierzają, nawet jeśli nie jest formalnie poprawne), można wytworzyć wartość NaN z 0./0. i sprawdzić, czy jeden z x != x .

+0

Można nawet utworzyć małe opakowanie kodu, które wykrywa, czy kod nie jest kompilowany jako C99 lub wyższy, a następnie definiuje makra 'NAN' i' isnan' do tych, których odpowiada. – Will

+0

@Will: oczywiście, chociaż nie sądzę, że '0./0.'formalnie spełnia wymagania makra' NAN' (mianowicie, że powinien być użyteczny do inicjalizacji statycznej); nadal nie jest to problemem dla większości użytkowników. –

+2

@StephenCanon '0./0.' jest wyrażeniem stałym, więc jest w porządku dla statycznej inicjalizacji. – ouah

4

Kwestia ta liczba może nie być poprawny według mojego „filtrować wtedy jak mogę zwrócić jakąś wartość niepowodzenie oznaczającego

Zamiast porównując liczbę przed NaN można użyć tego:

if (x != x) // x is NaN 

jak wspomniano w C można użyć tego wyrażenia 0.f/0.f, aby wytworzyć wartość NaN float w C89.

+0

OP nie pytał, jak sprawdzić NaN. –

-2

coś takiego

if(your_variable != your_variable) 
{ 
    return 0; //catch 0 as the failure returned value 
} 
else 
{ 
    //your code 
} 
+0

-1 ponieważ ta odpowiedź niczego nie wyjaśnia, ale zawiera kod, który byłby bardzo mylący dla każdego, kto nie jest już w stanie wiedzieć o tym, jak używać NaN i może go natychmiast zauważyć. Również dlatego, że '0' może być całkiem rozsądną wartością zwracaną. –

2

nie można zrobić, że trzeba dwie zmienne powrócił, jeden dla wartości, po jednym dla flagi awarii.

Na przykład można ustawić rzeczy, aby funkcja powróciła true w przypadku normalnej pracy. false w przypadku awarii (NaN).

Zmienna przechowująca wynik jest przekazywana jako odniesienie jako parametr i będzie utrzymywać powracającą wartość w przypadku powodzenia.

BOOL myFunction(int inInt, float inFloat, float *outResult) 
{ 
    /* 
     PROCESSING HERE 
    */ 

    // in case of failure 

    if(/* failure condition here */) 
    { 
     *outResult = 0; 
     return false; 
    } 

    *outResult = /* your result */ 

    return true; 
} 


// how to use the function 

int a; 
float b; 
float result; 
BOOL success; 

success = myFunction(a, b, &result); 

if(success) 
{ 
    // do whatever with your "result" 
} 
else 
{ 
    // NaN 
}