orlp
orlp

Reputation: 117691

What does the function remquo do and what can it be used for?

Reading through the C specs I found this function:

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 functions compute the same remainder as the remainder functions. In the object pointed to by quo they store a value whose sign is the sign of x/y and whose magnitude is congruent modulo 2^n to the magnitude of the integral quotient of x/y, where n is an implementation-defined integer greater than or equal to 3.

The remquo functions return x REM y. If y is zero, the value stored in the object pointed to by quo is unspecified and whether a domain error occurs or the functions return zero is implementation defined.

I understand what it returns, it returns fmod(x, y), but I don't understand the whole quo part. Is it semantically equal to this?

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

And my last question, for what could this function be useful?

Upvotes: 9

Views: 2351

Answers (3)

cruncher
cruncher

Reputation: 111

A typical usage of remquo() is the reduction of trigonometry function arguments. The last 3 bits of the quotient would allow one to tell which semi-quadrant an angle resides in, after a reduction modulo Pi/4, and to convert the original trig call into another trig call over an angle within the [0,Pi/4) interval (the new trig function could be different). The latter is usually computed via a Pade approximation.

Upvotes: 11

ugoren
ugoren

Reputation: 16441

EDIT: As Jeffrey Scofield said in his answer, the returned quotient really isn't x/y, but the low 3 bits (plus sign) of the quotient.

It's equivalent to (up to type differences):

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

Where rem is the return value, and quo is returned as an output parameter.
Its advantage over the above syntax is that it does just one division operation.

Upvotes: 4

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66803

It seems pretty clear that remquo does not give the value of x / y. It only gives a few low bits of the quotient. Here's an example:

#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

I get this same answer for OS X 10.8.2 (Xcode 4.6) and on a Linux system. The full quotient is 29629, and 5 is the low 3 bits thereof.

It's worth noting that the quotient can very easily be too large to be represented as an int. So really the best you can do is to give some low bits.

At any rate, this is not "language lawyerese." The specification is telling you something pretty specific.

Upvotes: 9

Related Questions