0

So I have the following code:

#include <stdio.h>

unsigned long int fibonacci()
{
    static int count = -1;
    static int f1 = 0;
    static int f2 = 1;

    count++;

    if(count == 0 || count == 1) {
        return count;
    } else {
        int f3 = f1 + f2;
        f1 = f2;
        f2 = f3;

        return f3;
    }
}

int main()
{
    int i;
    for(i = 1; i <= 50; i++) {
        printf("\n%i: %li", i, fibonacci());
    }

    return 0;
}

For the 48th fibonacci number, the output is -1323752223 indicating that the initial number was too large for the data type of the variable. The 48th fibonacci number is 2971215073 but google says the data type long int can handle numbers up to over 4 billion. So why can't it handle a number barely under 3 billion?

12
  • 1
    There is no guarantee that long int is able to represent numbers this large. That is different from platform to platform. Commented Dec 12, 2024 at 12:32
  • 3
    Re “google says the data type long int can handle…”: Google cannot tell you what numbers long int can handle because it is not a fixed limit. It varies by C implementation. In some C implementations, the maximum long int is 2,147,483,647, in others it is 9,223,372,036,854,775,807, and it could be other values. Do not just Google things and use some part of what you find without understanding it. Commented Dec 12, 2024 at 12:32
  • 3
    Note also your actual calculations use int. Commented Dec 12, 2024 at 12:37
  • 1
    You should replace all int and long int (which is the same as int on many platforms) with long long int or even unsigned long long int as you don't deal with negative numbers, then it might work. Also read this SO article: stackoverflow.com/q/18971732/898348 Commented Dec 12, 2024 at 12:42
  • 2
    Side note totally unrelated to your problem: the program design using static variables is at least questionable. Commented Dec 12, 2024 at 12:50

1 Answer 1

4

A long is a signed type and it must be large enough to at least handle the values -231-1 to 231-1.

Since C nowadays uses two's complement only, that means that the value range must at least be -2147483648 to 2147483647.

but google says the data type long int can handle numbers up to over 4 billion

No, that's an unsigned long which can handle values up to at least 232-1 = 4.29 billion.

Notably, most ABI specify long as 32 bits but a few specify it as 64 bits. Why it is a non-portable type and we are much better off using the portable types int32_t or int64_t.

Sign up to request clarification or add additional context in comments.

5 Comments

With C23 release last month, min limit is at least -2^31 - 0.
@chux Who knows, they botched that whole chapter. It appears that there is no longer any normative reference of what ULONG_MAX should at least be. Informative appendixes do not count.
Hmmm, With, C23 5.2.4.2.1 I read type unsigned long int --> ULONG_WIDTH is at least 32, and long int has LONG_WIDTH same as ULONG_WIDTH and LONG_MIN is then -2^(ULONG_WIDTH -1). This leads to LONG_MIN <= -2147483648. Perhaps a spec wording is squishy in that section?
@chux This part was crystal clear in previous versions of the standard and now they messed it up. There's no relation between the number of bits and the minimum value. Particularly since the ridiculous part (6.2.6.2) where C allows padding bits in integer types was not removed. How many of ULONG_WIDTH are padding bits? Who can tell. C23 is just one big editorial fiasco to the point where I'm losing faith in it. We have to wait for the no doubt massive technical corrigendum before considering using C23.
"How many of ULONG_WIDTH are padding bits?" --> As I read it, none, given BOOL_WIDTH 1 - implying at least 7 padding bits. Padding bits would be the difference of sizeof(type)*CHAR_BITS - type_WIDTH. IAC, yes, it not as clear as before. I suspect any update to be more clear will be informative. Yes C23 has much birthing pains. For me, it is the optional inclusion of decimal FP types that will impact us the most. IAC,MC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.