unsafe_where_true
unsafe_where_true

Reputation: 6300

how can something be bigger than (unsigned long long) > LONG_MAX?

I found this code in an algorithm I need to update:

 if (value > (unsigned long long) LONG_MAX)

EDIT: value is the result of a division of two uint64_t numbers.

I understand that (unsigned long long) LONG_MAX is a VERY big number:

   #include "stdio.h"
   #include "limits.h"

   int main() {
     unsigned long long ull = (unsigned long long) LONG_MAX;
     printf("%lu",ull);
     return 0;
   }

prints 9223372036854775807

So what I am comparing here? In what case this if statement will evaluate to true?

Upvotes: 5

Views: 1724

Answers (3)

John Bollinger
John Bollinger

Reputation: 180181

how can something be bigger than (unsigned long long) > LONG_MAX?

Easily. LONG MAX is the maximum value that can be represented as a long int. Converting that to unsigned long long does not change its value, only its data type. The maximum value that can be represented as an unsigned long int is larger on every C implementation you're likely to meet. The maximum value of long long int is larger on some, and the maximum value of unsigned long long int is, again, larger on every C implementation you're likely to meet (much larger on some).

However, this ...

     unsigned long long ull = (unsigned long long) LONG_MAX;
     printf("%lu",ull);

... is not a conforming way to investigate the value in question because %lu is a formatting directive for type unsigned long, not unsigned long long. The printf call presented therefore has undefined behavior.

I found this code in an algorithm I need to update:

 if (value > (unsigned long long) LONG_MAX)

EDIT: value is the result of a division of two uint64_t numbers.

[...]

In what case this if statement will evaluate to true?

Supposing that value has type uint64_t, which is probably the same as unsigned long long in your implementation, the condition in that if statement will evaluate to true at least when the most-significant bit of value is set. If your long int is only 32 bits wide, however, then the condition will evaluate to true much more widely than that, because there are many 64-bit integers that are larger than the largest value representable as a signed 32-bit integer.

I would be inclined to guess that the code was indeed written under the assumption that long int is 32 bits wide, so that the if statement asks a very natural question: "can the result of the previous uint64_t division be represented as a long?" In fact, that's what the if statement is evaluating in any case, but it makes more sense if long is only 32 bits wide, which is typical of 32-bit computers and standard on both 32- and 64-bit Windows.

Upvotes: 4

Vasfed
Vasfed

Reputation: 18454

LONG_MAX is maximum value for a signed long. By standard it should be >= +2147483647 (fits in 32 bit signed)

There's also ULLONG_MAX for unsigned long long, which is currently most often 18446744073709551615. The standard mandates that to be >= than 9223372036854775807

Upvotes: 3

dbush
dbush

Reputation: 223739

A float or double can be larger than that. Appendix Ep5 of the C standard states that either type must be able to hold a value at least as large as 1E37 which is a larger value than LONG_MAX which must be at least 2147483647:

The values given in the following list shall be replaced by implementation-defined constant expressions with values that are greater than or equal to those shown:

#define DBL_MAX 1E+37
#define FLT_MAX 1E+37
#define LDBL_MAX 1E+37

So if value is either of those types, it could evaluate to true.

EDIT:

Since value is a uint64_t, whose max value is 18446744073709551615, this can also be larger than LONG_MAX.

Upvotes: 5

Related Questions