0

I'm learning C++ and i have this code:

long long unsigned number;
cout << "Introduce a non negative number: \n";
cin >> number;
cout << "The number is equal to: " << number << endl;
cout << number*number;

When i introduce a negative value, per example -1 the message display that the number is equal to 18446744073709551615, and that is fine because i defined long long as a non negative number, so this number is something like an error.

What seems weird to me is that the square of the number gives the correct value, that is 1 in the case of -1 as input.

Despite the fact that the data entered by keyboard is not correct regarding the data type (unsigned), C ++ continues to giving the original input value(-1) as if it were stored somewhere.

So, where is C++ saving that value? How i can get it?

Similarly if i save the square as:

int a = number*number, per example in the case of input -1, a = 1

But when i do cout << a/n; its show 0 instead of 1/1 = 1 (Which I suppose is related to this)

ESCM
  • 269
  • 2
  • 13
  • 3
    This is because the binary representation of the numbers -1 and 18446744073709551615 is the same. The difference is whether you are treating it as a signed number or unsigned number. Please refer to https://stackoverflow.com/questions/40608111/why-is-18446744073709551615-1-true – Aziz May 17 '20 at 16:54

1 Answers1

3

This is because of modular arithmetic. When you assign -1 to an unsigned number, it gets stored as a number of the form 2^n - 1 (n depends on the archtecture, but is the largest possible positive number of that type).

All operations on values of this type follow the same modular arithmetic. So when you multiply 2 -1s, you are actually doing:

=> (2^n - 1) x (2^n - 1) mod 2^n
=> 2^(2n) -2^(n+1) + 1 mod 2^n
=> 1 mod 2^n  

Explaining the result of 1.

Note that the program is not saving the value of -1 anywhere, and the result you see is purely due to the modular arithmetic rules.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • I'm kinda surprised the read even occurred. The formatted input was expecting an unsigned integer, and it obviously didn't get one when the OP inputted -1. – StoryTeller - Unslander Monica May 17 '20 at 16:58
  • @StoryTeller-UnslanderMonica Hmm, seems that from c++17, cin is guaranteed to read `-1`, and assign the result given by passing it to `strtoull`. – cigien May 17 '20 at 17:07