Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't Assign 64 Bit Number to 64 Bit Min in C++

Tags:

c++

64-bit

I'm new to C++, so sorry if this sounds like a dumb question. I'm attempting to assign the 64 bit minimum (-9223372036854775808) to an int64_t (from cstdint), however I'm getting the current error message:

main.cpp:5:27: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]
int64_t int_64_min = -9223372036854775808;

The code is as follows:

#include <iostream>
#include <cstdint>

int main() {
    int64_t int_64_min = -9223372036854775808;
    std::cout << int_64_min << std::endl;
    std::cout << INT64_MIN << std::endl;
    return 0;
}

Am I missing something obvious?

like image 476
19UV Avatar asked Dec 31 '22 19:12

19UV


2 Answers

This is exactly why the INT_MIN family of macros are often defined like -INT_MAX - 1 on a 2's complement platform (virtually ubiquitous and compulsory from C++20).

There is no such thing as a negative literal in C++: just the unary negation of a positive number which produces a compile time evaluable constant expression.

9223372036854775808 is too big to fit into a 64 bit signed integral type, so the behavior of negating this and assigning to a signed 64 bit integral type is implementation defined.

Writing -9223372036854775807 - 1 is probably what your C++ standard library implementation does. If I were you, I'd use INT64_MIN directly or std::numeric_limits<std::int64_t>::min().

like image 120
Bathsheba Avatar answered Jan 11 '23 19:01

Bathsheba


The problem is that -9223372036854775808 is not a literal. 9223372036854775808 is a literal, and -9223372036854775808 is an expression consisting of that literal with a unary - applied to it.

All unsuffixed decimal literals are of type int, long int, or long long int. Since 9223372036854775808 is 263, it's bigger than the maximum value of long long int (assuming long long int is 64 bits, which it almost certainly is).

The simplest solution is to use the INT64_MIN macro defined in <cstdint>.

Aside from that, the problem is that there are no literals for negative values. Another solution is to replace -9223372036854775808 by -9223372036854775807-1 -- or by (-9223372036854775807-1) to avoid ambiguity. (The <cstdint> header very likely does something similar).

like image 42
Keith Thompson Avatar answered Jan 11 '23 17:01

Keith Thompson