8

If I do

 int n = 100000;
 long long x = n * n;

then x == 1410065408

1410065408 is 2^31, yet I expect x to be 64 bit

What is going on? I'm using VSC++ ( default VS c++ compiler )

Christo S. Christov
  • 2,268
  • 3
  • 32
  • 57
  • 1
    You may want to read this: http://en.cppreference.com/w/cpp/language/implicit_conversion , https://msdn.microsoft.com/en-us/library/aetzh118.aspx – Jesper Juhl Jul 23 '16 at 17:43
  • Aside: if you need a 64-bit type, you should usually prefer `int64_t` to `long long`. Similarly, if you need a 32-bit type, you should prefer `int32_t` to `int`. (aside #2: `int` isn't actually guaranteed to be 32 bits! It could be, for example, 64 bits or 16 bits, or even something exotic like 37 bits. Although I think MSVC insists on 32 bits) –  Jul 23 '16 at 21:34

3 Answers3

23

n*n is too big for an int because it is equal to 10^10. The (erroneous) result gets stored as a long long.

Try:

long long n = 100000;
long long x = n*n;

Here's an answer that references the standard that specifies that the operation long long x = (long long)n*n where n is an int will not cause data loss. Specifically,

If both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.

Since the functional cast has the highest precedence here, it converts the left multiplicand to a long long. The right multiplicand of type int gets converted to a long long according to the standard. No loss occurs.

Community
  • 1
  • 1
Jossie Calderon
  • 1,393
  • 12
  • 21
3

Declaring n as a long long is the best solution as mentioned previously.

Just as a quick clarification to the original post, 1410065408 is not 2^31, the value comes about as follows:

100,000 ^ 2 = 10,000,000,000 which exists in binary form as:

10 0101 0100 0000 1011 1110 0100 0000 0000

C++ integers are strictly 32 bits in memory. Therefore, the front two bits are ignored and the value is stored in memory as binary:

0101 0100 0000 1011 1110 0100 0000 0000

In decimal, this is equal to exactly 1410065408.

Dan
  • 474
  • 1
  • 7
  • 16
2

Edit - This is another solution to the problem; what this will do is cast the integer values to a long long before the multiplication so you don't get truncation of bits.

Original Posting

int n = 100000;
long long x = static_cast<long long>( n ) * static_cast<long long>( n );

Edit - The original answer provided by Jossie Calderon was already accepted as a valid answer and this answer adds another valid solution.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • 1
    Although this doesn't answer the question ("*why* is it caused?"), it is another solution to the exercise. – Jossie Calderon Jul 23 '16 at 18:09
  • 1
    @Chris probably it will produce exactly same code as what I suggested, it is just more formal. `static_cast` can have nice benefits if you use it right but for your purpose there is no need to make it so long. And you don't need to cast all parameters only one. – Logman Jul 23 '16 at 18:28
  • When in doubt use the casting modifiers; `static_cast<>(), dynamic_cast<>(), reinterpret_cast<>(), etc.` – Francis Cugler Jul 23 '16 at 21:45
  • @JossieCalderon Correct; this question already had an accepted answers so there was no reason to go back and explain it all over again; so I just provided another possible solution to the same problem. – Francis Cugler Jul 23 '16 at 21:47