Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Arithmetic operators

      From cppreference.com
      <c‎ |language
       
       
       
       

      Arithmetic operators apply standard mathematical operations to their operands.

      This section is incomplete
      Reason: consider a more general-purpose ToC for this and other tables that cover multiple topics
      Operator Operator name Example Result
      + unary plus+a the value ofa after promotions
      - unary minus-a the negative ofa
      + additiona+ b the addition ofa andb
      - subtractiona- b the subtraction ofb froma
      * producta* b the product ofa andb
      / divisiona/ b the division ofa byb
      % remaindera% b the remainder ofa divided byb
      ~ bitwise NOT~a the bitwise NOT ofa
      & bitwise ANDa& b the bitwise AND ofa andb
      | bitwise ORa| b the bitwise OR ofa andb
      ^ bitwise XORa^ b the bitwise XOR ofa andb
      << bitwise left shifta<< ba left shifted byb
      >> bitwise right shifta>> ba right shifted byb

      Contents

      [edit]Overflows

      Unsigned integer arithmetic is always performedmodulo 2n
      where n is the number of bits in that particular integer. E.g. forunsignedint, adding one toUINT_MAX gives0, and subtracting one from0 givesUINT_MAX.

      When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined: it may wrap around according to the rules of the representation (typically 2's complement), it may trap on some platforms or due to compiler options (e.g.-ftrapv in GCC and Clang), or may be completelyoptimized out by the compiler.

      [edit]Floating-point environment

      If#pragma STDC FENV_ACCESS is set toON, all floating-point arithmetic operators obey the current floating-pointrounding direction and report floating-point arithmetic errors as specified inmath_errhandling unless part of astatic initializer (in which case floating-point exceptions are not raised and the rounding mode is to nearest)

      [edit]Floating-point contraction

      Unless#pragma STDC FP_CONTRACT is set toOFF, all floating-point arithmetic may be performed as if the intermediate results have infinite range and precision, that is optimizations that omit rounding errors and floating-point exceptions that would be observed if the expression was evaluated exactly as written. For example, allows the implementation of(x*y)+ z with a single fused multiply-add CPU instruction or optimization ofa= x*x*x*x; astmp= x*x; a= tmp*tmp.

      Unrelated to contracting, intermediate results of floating-point arithmetic may have range and precision that is different from the one indicated by its type, seeFLT_EVAL_METHOD

      [edit]Unary arithmetic

      The unary arithmetic operator expressions have the form

      +expression (1)
      -expression (2)
      1) unary plus (promotion)
      2) unary minus (negation)
      expression - expression of anyarithmetic type

      Both unary plus and unary minus first applyintegral promotions to their operand, and then

      • unary plus returns the value after promotion
      • unary minus returns the negative of the value after promotion (except that the negative of a NaN is another NaN)

      The type of the expression is the type after promotion, and thevalue category is non-lvalue.

      [edit]Notes

      The unary minus invokes undefined behavior due to signed integer overflow when applied toINT_MIN,LONG_MIN, orLLONG_MIN, on typical (2's complement) platforms.

      In C++, unary operator+ can also be used with other built-in types such as arrays and functions, not so in C.

      Run this code
      #include <stdio.h>#include <complex.h>#include <limits.h> int main(void){char c='a';printf("sizeof char: %zu sizeof int: %zu\n",sizeof c,sizeof+c); printf("-1, where 1 is signed: %d\n",-1); // Defined behavior since arithmetic is performed for unsigned integer.// Hence, the calculation is (-1) modulo (2 raised to n) = UINT_MAX, where n is// the number of bits of unsigned int. If unsigned int is 32-bit long, then this// gives (-1) modulo (2 raised to 32) = 4294967295printf("-1, where 1 is unsigned: %u\n",-1u);  // Undefined behavior because the mathematical value of -INT_MIN = INT_MAX + 1// (i.e. 1 more than the maximum possible value for signed int)//// printf("%d\n", -INT_MIN); // Undefined behavior because the mathematical value of -LONG_MIN = LONG_MAX + 1// (i.e. 1 more than the maximum possible value for signed long)//// printf("%ld\n", -LONG_MIN); // Undefined behavior because the mathematical value of -LLONG_MIN = LLONG_MAX + 1// (i.e. 1 more than the maximum possible value for signed long long)//// printf("%lld\n", -LLONG_MIN); doublecomplex z=1+2*I;printf("-(1+2i) = %.1f%+.1f\n",creal(-z),cimag(-z));}

      Possible output:

      sizeof char: 1 sizeof int: 4-1, where 1 is signed: -1-1, where 1 is unsigned: 4294967295-(1+2i) = -1.0-2.0

      [edit]Additive operators

      The binary additive arithmetic operator expressions have the form

      lhs+rhs (1)
      lhs-rhs (2)
      1) addition:lhs andrhs must be one of the following
      • both havearithmetic types, including complex and imaginary
      • one is a pointer to complete object type, the other has integer type
      2) subtraction:lhs andrhs must be one of the following
      • both havearithmetic types, including complex and imaginary
      • lhs has pointer to complete object type,rhs has integer type
      • both are pointers to complete objects ofcompatible types, ignoring qualifiers

      [edit]Arithmetic addition and subtraction

      If both operands havearithmetic types, then

      • first,usual arithmetic conversions are performed
      • then, the values of the operands after conversions are added or subtracted following the usual rules of mathematics (for subtraction,rhs is subtracted fromlhs), except that
      • if one operand is NaN, the result is NaN
      • infinity minus infinity is NaN andFE_INVALID is raised
      • infinity plus the negative infinity is NaN andFE_INVALID is raised

      Complex and imaginary addition and subtraction are defined as follows (note the result type is imaginary if both operands are imaginary and complex if one operand is real and the other imaginary, as specified by the usual arithmetic conversions):

      + or - u iv u + iv
      x x ± u x ± iv (x ± u) ± iv
      iy ±u + iy i(y ± v) ±u + i(y ± v)
      x + iy (x ± u) + iy x + i(y ± v) (x ± u) + i(y ± v)


      Run this code
      // work in progress// note: take part of the c/language/conversion example

      [edit]Pointer arithmetic

      • If the pointerP points at an element of an array with indexI, then
      • P+N andN+P are pointers that point at an element of the same array with indexI+N
      • P-N is a pointer that points at an element of the same array with indexI-N

      The behavior is defined only if both the original pointer and the result pointer are pointing at elements of the same array or one past the end of that array. Note that executing p-1 when p points at the first element of an array is undefined behavior and may fail on some platforms.

      • If the pointerP1 points at an element of an array with indexI (or one past the end) andP2 points at an element of the same array with indexJ (or one past the end), then
      • P1-P2 has the value equal toI-J and the typeptrdiff_t (which is a signed integer type, typically half as large as the size of the largest object that can be declared)

      The behavior is defined only if the result fits inptrdiff_t.

      For the purpose of pointer arithmetic, a pointer to an object that is not an element of any array is treated as a pointer to the first element of an array of size 1.

      Run this code
      // work in progressint n=4, m=3;int a[n][m];// VLA of 4 VLAs of 3 ints eachint(*p)[m]= a;// p == &a[0]p= p+1;// p == &a[1] (pointer arithmetic works with VLAs just the same)(*p)[2]=99;// changes a[1][2]

      [edit]Multiplicative operators

      The binary multiplicative arithmetic operator expressions have the form

      lhs*rhs (1)
      lhs/rhs (2)
      lhs%rhs (3)
      1) multiplication.lhs andrhs must havearithmetic types
      2) division.lhs andrhs must havearithmetic types
      3) remainder.lhs andrhs must haveinteger types

      [edit]Multiplication

      The binary operator * performs multiplication of its operands (after usual arithmetic conversions) following the usual arithmetic definitions, except that

      • if one operand is a NaN, the result is a NaN
      • multiplication of infinity by zero gives NaN andFE_INVALID is raised
      • multiplication of infinity by a nonzero gives infinity (even for complex arguments)

      Because in C, anycomplex value with at least one infinite part is an infinity even if its other part is a NaN, the usual arithmetic rules do not apply to complex-complex multiplication. Other combinations of floating operands follow the following table:

      * u iv u + iv
      x xu i(xv) (xu) + i(xv)
      iy i(yu) −yv (−yv) + i(yu)
      x + iy (xu) + i(yu) (−yv) + i(xv)special rules

      Besides infinity handling, complex multiplication is not allowed to overflow intermediate results, except when#pragma STDC CX_LIMITED_RANGE is set toON, in which case the value may be calculated as if by(x+iy)×(u+iv) = (xu-yv)+i(yu+xv), as the programmer assumes the responsibility of limiting the range of the operands and dealing with the infinities.

      Despite disallowing undue overflow, complex multiplication may raise spurious floating-point exceptions (otherwise it is prohibitively difficult to implement non-overflowing versions)

      Run this code
      #include <stdio.h>#include <stdio.h>#include <complex.h>#include <math.h>int main(void){  // TODO simpler cases, take some from C++  doublecomplex z=(1+0*I)*(INFINITY+ I*INFINITY);// textbook formula would give// (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN// but C gives a complex infinityprintf("%f + i*%f\n",creal(z),cimag(z)); // textbook formula would give// cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN// but C gives  ±∞+i*nandoublecomplex y=cexp(INFINITY+ I*NAN);printf("%f + i*%f\n",creal(y),cimag(y)); }

      Possible output:

      inf + i*inf inf + i*nan

      [edit]Division

      The binary operator/ divides the first operand by the second (after usual arithmetic conversions) following the usual arithmetic definitions, except that

      • when the type after usual arithmetic conversions is an integer type, the result is the algebraic quotient (not a fraction),rounded in implementation-defined direction(until C99)truncated towards zero(since C99)
      • if one operand is a NaN, the result is a NaN
      • if the first operand is a complex infinity and the second operand is finite, then the result of the/ operator is a complex infinity
      • if the first operand is finite and the second operand is a complex infinity, then the result of the/ operator is a zero.

      Because in C, anycomplex value with at least one infinite part as an infinity even if its other part is a NaN, the usual arithmetic rules do not apply to complex-complex division. Other combinations of floating operands follow the following table:

      / u iv
      x x/u i(−x/v)
      iy i(y/u) y/v
      x + iy (x/u) + i(y/u) (y/v) + i(−x/v)

      Besides infinity handling, complex division is not allowed to overflow intermediate results, except when#pragma STDC CX_LIMITED_RANGE is set toON, in which case the value may be calculated as if by(x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u2
      +v2
      )
      , as the programmer assumes the responsibility of limiting the range of the operands and dealing with the infinities.

      Despite disallowing undue overflow, complex division may raise spurious floating-point exceptions (otherwise it is prohibitively difficult to implement non-overflowing versions)

      If the second operand is zero, the behavior is undefined, except that if the IEEE floating-point arithmetic is supported, and the floating-point division is taking place, then

      • Dividing a non-zero number by ±0.0 gives the correctly-signed infinity andFE_DIVBYZERO is raised
      • Dividing 0.0 by 0.0 gives NaN andFE_INVALID is raised

      [edit]Remainder

      The binary operator % yields the remainder of the division of the first operand by the second (after usual arithmetic conversions).

      The sign of the remainder is defined in such a way that if the quotienta/b is representable in the result type, then(a/b)*b+ a%b== a.

      If the second operand is zero, the behavior is undefined.

      If the quotienta/b is not representable in the result type, the behavior of botha/b anda%b is undefined (that meansINT_MIN%-1 is undefined on 2's complement systems)

      Note: the remainder operator does not work on floating-point types, the library functionfmod provides that functionality.

      [edit]Bitwise logic

      The bitwise arithmetic operator expressions have the form

      ~rhs (1)
      lhs&rhs (2)
      lhs|rhs (3)
      lhs^rhs (4)
      1) bitwise NOT
      2) bitwise AND
      3) bitwise OR
      4) bitwise XOR

      where

      lhs,rhs - expressions of integer type

      First, operators&,^, and| performusual arithmetic conversions on both operands and the operator~ performsinteger promotions on its only operand.

      Then, the corresponding binary logic operators are applied bitwise; that is, each bit of the result is set or cleared according to the logic operation (NOT, AND, OR, or XOR), applied to the corresponding bits of the operands.

      Note: bitwise operators are commonly used to manipulate bit sets and bit masks.

      Note: for unsigned types (after promotion), the expression~E is equivalent to the maximum value representable by the result type minus the original value ofE.

      Run this code
      #include <stdio.h>#include <stdint.h> int main(void){uint32_t a=0x12345678;uint16_t mask=0x00f0; printf("Promoted mask:\t%#010x\n""Value:\t\t%#x\n""Setting bits:\t%#x\n""Clearing bits:\t%#x\n""Selecting bits:\t%#010x\n"           , mask           , a           , a| mask           , a& ~mask           , a& mask);}

      Possible output:

      Promoted mask:  0x000000f0Value:          0x12345678Setting bits:   0x123456f8Clearing bits:  0x12345608Selecting bits: 0x00000070

      [edit]Shift operators

      The bitwise shift operator expressions have the form

      lhs<<rhs (1)
      lhs>>rhs (2)
      1) left shift oflhs byrhs bits
      2) right shift oflhs byrhs bits

      where

      lhs,rhs - expressions of integer type

      First,integer promotions are performed, individually, on each operand (Note: this is unlike other binary arithmetic operators, which all perform usual arithmetic conversions). The type of the result is the type oflhs after promotion.

      The behavior is undefined ifrhs is negative or is greater or equal the number of bits in the promotedlhs.

      For unsignedlhs, the value ofLHS << RHS is the value ofLHS * 2RHS
      , reduced modulo maximum value of the return type plus 1 (that is, bitwise left shift is performed and the bits that get shifted out of the destination type are discarded). For signedlhs with nonnegative values, the value ofLHS << RHS isLHS * 2RHS
      if it is representable in the promoted type oflhs, otherwise the behavior is undefined.

      For unsignedlhs and for signedlhs with nonnegative values, the value ofLHS >> RHS is the integer part ofLHS / 2RHS
      . For negativeLHS, the value ofLHS >> RHS is implementation-defined where in most implementations, this performs arithmetic right shift (so that the result remains negative). Thus in most implementations, right shifting a signedLHS fills the new higher-order bits with the original sign bit (i.e. with 0 if it was non-negative and 1 if it was negative).

      Run this code
      #include <stdio.h>enum{ONE=1, TWO=2};int main(void){char c=0x10;unsignedlonglong ulong_num=0x123;printf("0x123 << 1  = %#llx\n""0x123 << 63 = %#llx\n"// overflow truncates high bits for unsigned numbers"0x10  << 10 = %#x\n",// char is promoted to int           ulong_num<<1, ulong_num<<63, c<<10);longlong long_num=-1000;printf("-1000 >> 1 = %lld\n", long_num>> ONE);// implementation defined}

      Possible output:

      0x123 << 1  = 0x2460x123 << 63 = 0x80000000000000000x10  << 10 = 0x4000-1000 >> 1 = -500

      [edit]References

      • C17 standard (ISO/IEC 9899:2018):
      • 6.5.3.3 Unary arithmetic operators (p: 64)
      • 6.5.5 Multiplicative operators (p: 66)
      • 6.5.6 Additive operators (p: 66-68)
      • 6.5.7 Bitwise shift operators (p: 68)
      • 6.5.10 Bitwise AND operator (p: 70)
      • 6.5.11 Bitwise exclusive OR operator (p: 70)
      • 6.5.12 Bitwise inclusive OR operator (p: 70-71)
      • C11 standard (ISO/IEC 9899:2011):
      • 6.5.3.3 Unary arithmetic operators (p: 89)
      • 6.5.5 Multiplicative operators (p: 92)
      • 6.5.6 Additive operators (p: 92-94)
      • 6.5.7 Bitwise shift operators (p: 94-95)
      • 6.5.10 Bitwise AND operator (p: 97)
      • 6.5.11 Bitwise exclusive OR operator (p: 98)
      • 6.5.12 Bitwise inclusive OR operator (p: 98)
      • C99 standard (ISO/IEC 9899:1999):
      • 6.5.3.3 Unary arithmetic operators (p: 79)
      • 6.5.5 Multiplicative operators (p: 82)
      • 6.5.6 Additive operators (p: 82-84)
      • 6.5.7 Bitwise shift operators (p: 84-85)
      • 6.5.10 Bitwise AND operator (p: 87)
      • 6.5.11 Bitwise exclusive OR operator (p: 88)
      • 6.5.12 Bitwise inclusive OR operator (p: 88)
      • C89/C90 standard (ISO/IEC 9899:1990):
      • 3.3.3.3 Unary arithmetic operators
      • 3.3.5 Multiplicative operators
      • 3.3.6 Additive operators
      • 3.3.7 Bitwise shift operators
      • 3.3.10 Bitwise AND operator
      • 3.3.11 Bitwise exclusive OR operator
      • 3.3.12 Bitwise inclusive OR operator

      [edit]See also

      Operator precedence

      Common operators
      assignmentincrement
      decrement
      arithmeticlogicalcomparisonmember
      access
      other

      a= b
      a+= b
      a-= b
      a*= b
      a/= b
      a%= b
      a&= b
      a|= b
      a^= b
      a<<= b
      a>>= b

      ++a
      --a
      a++
      a--

      +a
      -a
      a+ b
      a- b
      a* b
      a/ b
      a% b
      ~a
      a& b
      a| b
      a^ b
      a<< b
      a>> b

      !a
      a&& b
      a|| b

      a== b
      a!= b
      a< b
      a> b
      a<= b
      a>= b

      a[b]
      *a
      &a
      a->b
      a.b

      a(...)
      a, b
      (type) a
      a? b: c
      sizeof


      _Alignof
      (since C11)
      (until C23)

      alignof
      (since C23)

      C++ documentation forArithmetic operators
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=c/language/operator_arithmetic&oldid=176253"

      [8]ページ先頭

      ©2009-2025 Movatter.jp