Danny Danny - 27 days ago 5
C Question

Fast input for long and long long in C?

So i have been using this function for codechef problems for quite some while now as a fast input method for integers.

My question is how this actually works,what is fgetc_unlocked(stdin) (even though its commented) and most importantly how can I optimise it to run for long and long long.

Here is the code:

inline void Scan_f(int a)
{
char c = 0;
while(c<33)//shouldn't value of c to compare be less than 9 as digit vary between 0 to 9??
//c = fgetc_unlocked(stdin);
c = getc(stdin);
a = 0;
while(c>33)
{
a = a*10 + c - '0';
//c = fgetc_unlocked(stdin);
c = getc(stdin);
}

M.M M.M
Answer Source

It looks to me as if the code should be:

inline unsigned long long Scan_f()
{
    int c;
    do
        c = fgetc(stdin);
    while ( (c < '0' || c > '9') && c != EOF );

    unsigned long long a = 0;
    while ( c >= '0' && c <= '9' )
    {
        a = a*10 + (c - '0');
        c = fgetc(stdin);
    }
    return a;
}

In the code you posted, a is a parameter passed by value, so it's unclear how the calling function will find out about your changes to a.

The fgetc_unlocked function is supposed to be a faster version of fgetc. It's a GNU extension.

It doesn't make sense for a to be a signed type, as your parsing can never retrieve a negative value.

This version does not check for overflow; if you want to handle that possibility then you'll need to add in a check before doing a = a*10.

Don't worry about efficiency in the c < '0' etc. sections, the compiler will generate the optimal code for you already. They can handle simple situations like this pretty well. Certainly it can check that faster than it can read characters from whatever your input stream is; the input stream speed will be the bottleneck.