Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the exact value range for unsigned long?

I am working through the exercises in the book "Learn C the hard way". Exercise 7 asks the reader to find the value which makes the range of an unsigned long exceed.

Change long to unsigned long and try to find the number that makes it too big.

So my approach is to first get the size of an unsigned long on my machine:

printf("SIZEOF ULONG: %lu", sizeof(unsigned long));

This prints 8 as a result. So assuming that an unsigned long will take up 64 bits on my machine I looked up the maximum range on Wikipedia.

64-Bits (word, doubleword, longword, long long, quad, quadword, qword, int64)

  • Unsigned: From 0 to 18,446,744,073,709,551,615

I was expecting that declaring an unsigned long with the above value would compile without warnings until I increment the value by 1. The result is different though. compiling the following program results in a warning.

#include <stdio.h>
int main()
{
    unsigned long value = 18446744073709551615;
    printf("SIZEOF ULONG: %lu", sizeof(unsigned long));
    printf("VALUE: %lu", value);
    return 0;
}

bla.c: In function ‘main’:
bla.c:5:27: warning: integer constant is so large that it is unsigned
     unsigned long value = 18446744073709551615;
                           ^~~~~~~~~~~~~~~~~~~~

So why does gcc complain about the value being to large, I thought I already declared it as unsigned?

like image 702
チーズパン Avatar asked Feb 21 '19 18:02

チーズパン


People also ask

Is unsigned long 64-bit?

Maximum value of unsigned long long int in C++It is the largest (64 bit) integer data type in C++.

Does unsigned long have decimals?

Unsigned long can be indexed in a numeric or string form, representing integer values in the range [0, 18446744073709551615]. They can't have a decimal part.


1 Answers

Decimal integer constants have type int if they fit in that range, otherwise they have type long or long long. They do not have an unsigned type, and if the value is outside those signed ranges you get the warning. You need to add the ul suffix for the constant to have the proper type.

There’s also a much easier way to get the maximum value of this type without knowing its size. Just cast -1 to this type.

unsigned long value = (unsigned long)-1;
like image 66
dbush Avatar answered Oct 13 '22 00:10

dbush