0

I have faced a problem that makes me confused. Please refer following example code

(This is an example to reproduce the problem. The result is exactly the same as I found my code)


#include <iostream>

using namespace std;

int unsigned_SomeFcn(uint32_t data)
{
    int a = 2;
    int b = 1;
    return ((b-a)*(data - ((data >> 7) << 7))) >> 7;
}

int int_SomeFcn(int data)
{
    int a = 2;
    int b = 1;
    return ((b-a)*(data - ((data >> 7) << 7))) >> 7;
}

int main()
{
    int a = 2;
    int b = 1;
    uint32_t unsigned_data = 5685;
    int      int_data = 5685;
    
    cout << "unsigned SomeFcn : " << unsigned_SomeFcn(unsigned_data) << endl;
    cout << "int SomeFcn : " << int_SomeFcn(int_data) << endl;
    
    cout << "unsigned (data - ((data >> 7) << 7)) >> 7 : " 
         << (((b-a)*(unsigned_data - ((unsigned_data >> 7) << 7))) >> 7) << endl;
    cout << "int (data - ((data >> 7) << 7)) >> 7 : " 
         << (((b-a)*(int_data - ((int_data >> 7) << 7))) >> 7) << endl;

    return 0;
}

and here is the result:

unsigned SomeFcn : 33554431
int SomeFcn : -1
unsigned ((b-a)*(data - ((data >> 7) << 7))) : 4294967243
int ((b-a)*(data - ((data >> 7) << 7))) : -53

Why are they different? In this case, what type of signed and unsigned integer calculation result will be?

I have two functions that return (b-a)*(data - ((data >> 7) << 7)) >> 7.

The value which is multiplied to (b-a) is from an algorithm I am using.. it is just a combination of integer calculations.

As you can find above, the results are different as the type of argument changes. Since the data has a range of 0 to 16383, I decided to use uint32_t instead of int, but I got the incorrect result.

So I just tried to change the type of the data to int and got the correct one.

(b-a) is obviously -1, and (data- ((data>> 7) << 7)) is 53 when data is 5685. and the return type of the function is int, so the function should return (-53) >> 7 which is -1

Ricky
  • 11
  • 3
  • Also look at the [documentation of the shift operators]( https://en.cppreference.com/w/cpp/language/operator_arithmetic). Specifically *In any case, if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.* – Pepijn Kramer Jun 28 '23 at 06:05
  • 1
    oops the duplicate is for C. The correct C++ duplicates: [What happens when I mix signed and unsigned types in C++?](https://stackoverflow.com/q/25609091/995714), [how c++ handles the arithmetic between an int and an unsigned int?](https://stackoverflow.com/q/69245628/995714), [Why does C++ standard specify signed integer be cast to unsigned in binary operations with mixed signedness?](https://stackoverflow.com/q/43336218/995714), [Signed/unsigned comparison gives unexpected result](https://stackoverflow.com/q/23432199/995714) – phuclv Jun 28 '23 at 06:35

0 Answers0