2012-02-19 14 views
5

Czytając specyfikacji Ic znaleziono tę funkcję:Do czego służy funkcja remo i do czego można jej użyć?

double remquo(double x, double y, int *quo); 
float remquof(float x, float y, int *quo); 
long double remquol(long double x, long double y, 
    int *quo); 

The remquo funkcji obliczenia tego samego reszta jako remainder funkcji. W przedmiotem wskazywanego przez quo przechowują wartość, której znak jest znakiem x/y i którego wielkość jest przystający modulo 2^n do wielkości integralnego iloraz x/y, gdzie n jest implementacji z definicją liczbą całkowitą większą niż lub równą 3. do

W remquo zwracają x REM y. Jeśli y wynosi zero, wartość przechowywana w obiekcie wskazywanego przez quo jest unspeci fi kowane i czy występuje błąd domeny lub funkcje wrócić zerowy jest realizacja de fi ned.

rozumiem co to powraca, powraca fmod(x, y), ale nie rozumiem cały quo część. Czy jest semantycznie równa temu?

*quo = (int) x/y; 
*quo %= n; /* n implementation defined */ 

I moje ostatnie pytanie, na co ta funkcja może być przydatna?

+0

patrz także http://www.kernel.org/doc/man-pages/online/pages/man3/remquo.3.html i http://sourceware.org/bugzilla/show_bug.cgi?id=4449 – Christoph

+0

Użycie zostało odebrane w [to pytanie] (http://stackoverflow.com/questions/11074865/stdremquo-purpose-and-usage) –

+1

Również notatka z [cppreference] (http://en.cppreference.com/ w/cpp/numeric/math/remquo): Ta funkcja jest użyteczna przy wykonywaniu funkcji okresowych z okresem dokładnie przedstawianym jako wartość zmiennoprzecinkowa: podczas obliczania grzechu (πx) dla bardzo dużego x, wywołanie std :: sin może bezpośrednio powoduje duży błąd, ale jeśli argument funkcji zostanie najpierw zredukowany za pomocą std :: remquo, bity mniejszego rzędu ilorazu mogą być użyte do określenia znaku i oktanta wyniku w danym okresie, podczas gdy reszta może być używane do obliczania wartości z dużą precyzją. –

Odpowiedz

2

Edycja: Jeffrey Scofieldzie powiedział his answer, zwrócony iloraz naprawdę nie x/y, ale niskie 3 bitów (plus) ilorazu.

Jest to równoważne (do typu różnice)

quo = x/y; 
rem = x%y; 

przypadku rem się wartość powrotną i quo zawraca się jako parametr wyjściowy.
Jego przewagą nad powyższą składnią jest to, że wykonuje tylko jedną operację podziału.

+1

ugoren: o czym jest ta część? 'i którego wielkość jest zgodna modulo 2^n do wielkości integralnego ilorazu x/y, gdzie n jest liczbą całkowitą określoną w implementacji większą niż lub równą 3. ' – orlp

+2

To jest rozmowa z językiem programistycznym, która jest dość trudna do omówienia. czytać. Zasadniczo oznacza "równa się x/y", ale pozwala przepełnić liczbę całkowitą. – ugoren

+1

@ugoran: Ponieważ '2^3 == 8' zakładam, że pozwala to działać na implementacjach, w których' sizeof (int) == 1 byte'. Ale dlaczego nie wymusili tego 'n == sizeof (int)'? – orlp

5

Wydaje się całkiem jasne, że remquo robi nie podać wartość x/y. Daje tylko kilka małych bitów ilorazu. Oto przykład:

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

int main() 
{ 
    int quo; 
    double res = remquo(88888.0, 3.0, &quo); 
    printf("%f %d\n", res, quo); 
    return 0; 
} 
$ 
$ cc -o rq rq.c 
$ rq 
1.000000 5 

Otrzymuję tę samą odpowiedź dla OS X 10.8.2 (Xcode 4.6) i na systemie Linux. Pełny współczynnik wynosi 29629, a 5 to niskie 3 bity.

Warto zauważyć, że iloraz może z łatwością być zbyt duży, aby mógł być reprezentowany jako int. Więc naprawdę najlepsze, co możesz zrobić, to dać trochę niskich bitów.

W każdym razie nie jest to "język prawniczy". Specyfikacja mówi ci coś bardzo specyficznego.

+1

Muszę przyznać, że masz rację. Zwrócone 'quo' wygląda całkiem bezużyteczne, chociaż [ta odpowiedź] (http://lists.apple.com/archives/carbon-dev/2007/Dec/msg00354.html) wyjaśnia nieco jego cel. – ugoren

2

Typowym zastosowaniem funkcji remquo() jest redukcja argumentów funkcji trygonometrycznych. Ostatnie 3 bity ilorazu pozwoliłyby określić, w którym ćwiartce znajduje się kąt, po modulo redukcyjnym Pi/4, i przekształcić pierwotne wywołanie trywialne w inne wywołanie wyzwalania przez kąt w granicach [0, Pi/4) interwał (nowa funkcja wyzwalania może być inna). Ten ostatni jest zwykle obliczany przez przybliżenie Pade.