Implicit type conversion rules in C++ operators

后端 未结 9 2106
情书的邮戳
情书的邮戳 2020-11-22 00:21

I want to be better about knowing when I should cast. What are the implicit type conversion rules in C++ when adding, multiplying, etc. For example,

int + fl         


        
相关标签:
9条回答
  • 2020-11-22 00:24

    Caveat!

    The conversions occur from left to right.

    Try this:

    int i = 3, j = 2;
    double k = 33;
    cout << k * j / i << endl; // prints 22
    cout << j / i * k << endl; // prints 0
    
    0 讨论(0)
  • 2020-11-22 00:29

    My solution to the problem got WA(wrong answer), then i changed one of int to long long int and it gave AC(accept). Previously, I was trying to do long long int += int * int, and after I rectify it to long long int += long long int * int. Googling I came up with,

    1. Arithmetic Conversions

    Conditions for Type Conversion:

    Conditions Met ---> Conversion

    • Either operand is of type long double. ---> Other operand is converted to type long double.

    • Preceding condition not met and either operand is of type double. ---> Other operand is converted to type double.

    • Preceding conditions not met and either operand is of type float. ---> Other operand is converted to type float.

    • Preceding conditions not met (none of the operands are of floating types). ---> Integral promotions are performed on the operands as follows:

      • If either operand is of type unsigned long, the other operand is converted to type unsigned long.
      • If preceding condition not met, and if either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long.
      • If the preceding two conditions are not met, and if either operand is of type long, t he other operand is converted to type long.
      • If the preceding three conditions are not met, and if either operand is of type unsigned int, the other operand is converted to type unsigned int.
      • If none of the preceding conditions are met, both operands are converted to type int.

    2 . Integer conversion rules

    • Integer Promotions:

    Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int. Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators.

    • Integer Conversion Rank:

      • No two signed integer types shall have the same rank, even if they have the same representation.
      • The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
      • The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.
      • The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
      • The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
      • The rank of char shall equal the rank of signed char and unsigned char.
      • The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined but still subject to the other rules for determining the integer conversion rank.
      • For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.
    • Usual Arithmetic Conversions:

      • If both operands have the same type, no further conversion is needed.
      • If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
      • If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.
      • If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.
      • Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. Specific operations can add to or modify the semantics of the usual arithmetic operations.
    0 讨论(0)
  • 2020-11-22 00:34

    If you exclude the unsigned types, there is an ordered hierarchy: signed char, short, int, long, long long, float, double, long double. First, anything coming before int in the above will be converted to int. Then, in a binary operation, the lower ranked type will be converted to the higher, and the results will be the type of the higher. (You'll note that, from the hierarchy, anytime a floating point and an integral type are involved, the integral type will be converted to the floating point type.)

    Unsigned complicates things a bit: it perturbs the ranking, and parts of the ranking become implementation defined. Because of this, it's best to not mix signed and unsigned in the same expression. (Most C++ experts seem to avoid unsigned unless bitwise operations are involved. That is, at least, what Stroustrup recommends.)

    0 讨论(0)
  • 2020-11-22 00:37

    This answer is directed in large part at a comment made by @RafałDowgird:

    "The minimum size of operations is int." - This would be very strange (what about architectures that efficiently support char/short operations?) Is this really in the C++ spec?

    Keep in mind that the C++ standard has the all-important "as-if" rule. See section 1.8: Program Execution:

    3) This provision is sometimes called the "as-if" rule, because an implementation is free to disregard any requirement of the Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.

    The compiler cannot set an int to be 8 bits in size, even if it were the fastest, since the standard mandates a 16-bit minimum int.

    Therefore, in the case of a theoretical computer with super-fast 8-bit operations, the implicit promotion to int for arithmetic could matter. However, for many operations, you cannot tell if the compiler actually did the operations in the precision of an int and then converted to a char to store in your variable, or if the operations were done in char all along.

    For example, consider unsigned char = unsigned char + unsigned char + unsigned char, where addition would overflow (let's assume a value of 200 for each). If you promoted to int, you would get 600, which would then be implicitly down cast into an unsigned char, which would wrap modulo 256, thus giving a final result of 88. If you did no such promotions,you'd have to wrap between the first two additions, which would reduce the problem from 200 + 200 + 200 to 144 + 200, which is 344, which reduces to 88. In other words, the program does not know the difference, so the compiler is free to ignore the mandate to perform intermediate operations in int if the operands have a lower ranking than int.

    This is true in general of addition, subtraction, and multiplication. It is not true in general for division or modulus.

    0 讨论(0)
  • 2020-11-22 00:37

    The type of the expression, when not both parts are of the same type, will be converted to the biggest of both. The problem here is to understand which one is bigger than the other (it does not have anything to do with size in bytes).

    In expressions in which a real number and an integer number are involved, the integer will be promoted to real number. For example, in int + float, the type of the expression is float.

    The other difference are related to the capability of the type. For example, an expression involving an int and a long int will result of type long int.

    0 讨论(0)
  • 2020-11-22 00:41

    Arithmetic operations involving float results in float.

    int + float = float
    int * float = float
    float * int = float
    int / float = float
    float / int = float
    int / int = int
    

    For more detail answer. Look at what the section §5/9 from the C++ Standard says

    Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result.

    This pattern is called the usual arithmetic conversions, which are defined as follows:

    — If either operand is of type long double, the other shall be converted to long double.

    — Otherwise, if either operand is double, the other shall be converted to double.

    — Otherwise, if either operand is float, the other shall be converted to float.

    — Otherwise, the integral promotions (4.5) shall be performed on both operands.54)

    — Then, if either operand is unsigned long the other shall be converted to unsigned long.

    — Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.

    — Otherwise, if either operand is long, the other shall be converted to long.

    — Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

    [Note: otherwise, the only remaining case is that both operands are int ]

    0 讨论(0)
提交回复
热议问题