Home > OS >  Integer Arithmetics Going Wild
Integer Arithmetics Going Wild

Time:12-02

Please, could somebody explain what's happening under the hood there? The example runs on an Intel machine. Would the behavior be the same on other architectures?

Actually, I have a hardware counter which overruns every now and then, and I have to make sure that the intervals are always computed correctly. I thought that integer arithmetics should always do the trick but when there is a sign change, binary subtraction yields an overflow bit which appears to be actually interpreted as the sign.

Do I really have to handle the sign by myself or is there a more elegant way to compute the interval regardless of the hardware or the implementation?

TIA

  std::cout << "\nTest integer arithmetics\n";
  int8_t iFirst = -2;
  int8_t iSecond = 2;
  int8_t iResult = iSecond - iFirst;
  std::cout << "\n" << std::to_string(iSecond) << " - " << std::to_string(iFirst) << " = " << std::to_string(iResult);
  iResult = iFirst - iSecond;
  std::cout << "\n" << std::to_string(iFirst) << " - " << std::to_string(iSecond) << " = " << std::to_string(iResult);
  iFirst = SCHAR_MIN   1; iSecond = SCHAR_MAX - 2;
  iResult = iSecond - iFirst;
  std::cout << "\n" << std::to_string(iSecond) << " - " << std::to_string(iFirst) << " = " << std::to_string(iResult);
  iResult = iFirst - iSecond;
  std::cout << "\n" << std::to_string(iFirst) << " - " << std::to_string(iSecond) << " = " << std::to_string(iResult) << "\n\n";

And this is what I get:

Test integer arithmetics
2 - -2 = 4
-2 - 2 = -4
125 - -127 = -4
-127 - 125 = 4

CodePudding user response:

What happens with iResult = iFirst - iSecond is that first both variables iFirst and iSecond are promoted to int due to usual arithmetic conversion. The result is an int. That int result is truncated to int8_t for the assignment (in effect, the top 24 bits of the 32-bit int is cut away).

The int result of -127 - 125 is -252. With two's complement representation that will be 0xFFFFFF04. Truncation only leaves the 0x04 part. Therefore iResult will be equal to 4.

CodePudding user response:

the problem is that your variable is 8 bit. 8 bits can hold up to 256 numbers. So, your variables can only represent numbers within -128~127 range. Any number out of that range will give wrong output. Both of your last calculations produce numbers beyond the variable's range (252 and -252). There is no elegant or even possible way to handle it as it is. You can only handle the overflow bit yourself.

PS. This is not hardware problem. Any processor would give same results.

  • Related