why overflow happens on calculation depending on the data type when the type where the value is being assigned can hold it

前端 未结 5 2090
别那么骄傲
别那么骄傲 2021-01-28 02:10

Earlier I came up with something, which I solved, but it got me later let\'s take a look at a similar example of what I was on:

int b = 35000000; //35million
int         


        
5条回答
  •  天命终不由人
    2021-01-28 02:27

    Works (Output = 85):

    unsigned long b= 35000000;
    unsigned long n = ( 100 * 30000000 ) / b;
    

    Not here, using:

    #include 
    
    int main() {
        unsigned long b= 35000000;
        unsigned long n = ( 100 * 30000000 ) / b;
        std::cout << n << std::endl;
        return 0;
    }
    

    the output is 527049830640 (and the compiler warned about the overflow even with the default warning level).

    The point is that, as Mark Ransom already wrote, the type of an arithmetic operation is determined by the type of its operands.

    The type of the constant 100 is int, as is the type of the constant 30000000 (assuming 32-bit or larger ints, would be long int if int is 16 bits). So the multiplication is performed at type int, and with 32-bit ints it overflows. The overflow is undefined behaviour, but wrap-around is the most common manifestation of that undefined behaviour, resulting in the value -1294967296. Then the result of the multiplication is converted to the type of b (since that is an unsigned type and - in C terminology - its integer conversion rank is not smaller than that of int) for the division.

    Conversion to an unsigned integer type means reduction modulo 2^WIDTH. If the width of unsigned long is 32, the result of that last conversion is 2^32 - 1294967296 = 3000000000, resulting in the quotient 85. But if - as on my system - the width of unsigned long is 64 bits, the result of that conversion is 2^64 - 1294967296 = 18446744072414584320.

提交回复
热议问题