Reputation: 6300
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
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
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
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