diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Farithmetic_types.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Farithmetic_types.html')
| -rw-r--r-- | devdocs/c/language%2Farithmetic_types.html | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/devdocs/c/language%2Farithmetic_types.html b/devdocs/c/language%2Farithmetic_types.html new file mode 100644 index 00000000..d3423d5a --- /dev/null +++ b/devdocs/c/language%2Farithmetic_types.html @@ -0,0 +1,302 @@ + <h1 id="firstHeading" class="firstHeading">Arithmetic types</h1> <p><small>(See also <a href="type" title="c/language/type">type</a> for type system overview and <a href="../types" title="c/types">the list of type-related utilities</a> that are provided by the C library.)</small></p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <h3 id="Boolean_type"> Boolean type</h3> <ul><li> <span class="t-rev-inl t-until-c23"><span><code>_Bool</code> (also accessible as the macro <a href="../types" title="c/types"><code>bool</code></a>)</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> - type, capable of holding one of the two values: <span class="t-rev-inl t-until-c23"><span><code>1</code> and <code>0</code> (also accessible as the macros <a href="../types" title="c/types"><code>true</code></a> and <a href="../types" title="c/types"><code>false</code></a>)</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>true</code> and <code>false</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>. </li></ul> <p>Note that <a href="conversion" title="c/language/conversion">conversion</a> to <span class="t-rev-inl t-until-c23"><span>_Bool</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span>bool</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> does not work the same as conversion to other integer types: <code>(bool)0.5</code> evaluates to <code>true</code>, whereas <code>(int)0.5</code> evaluates to <code>0</code>.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Character_types"> Character types</h3> <ul> +<li> +<code>signed char</code> - type for signed character representation. </li> +<li> +<code>unsigned char</code> - type for unsigned character representation. Also used to inspect <a href="object" title="c/language/object">object representations</a> (raw memory). </li> +<li> +<code>char</code> - type for character representation. Equivalent to either <code>signed char</code> or <code>unsigned char</code> (which one is implementation-defined and may be controlled by a compiler commandline switch), but <code>char</code> is a distinct type, different from both <code>signed char</code> and <code>unsigned char</code>. </li> +</ul> <p>Note that the standard library also defines <a href="typedef" title="c/language/typedef">typedef</a> names <a href="../string/wide" title="c/string/wide"><code>wchar_t</code></a> <span class="t-rev-inl t-since-c11"><span>, <a href="../string/multibyte" title="c/string/multibyte"><code>char16_t</code></a> and <a href="../string/multibyte" title="c/string/multibyte"><code>char32_t</code></a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> to represent wide characters <span class="t-rev-inl t-since-c23"><span>and <a href="../string/multibyte" title="c/string/multibyte"><code>char8_t</code></a> for UTF-8 characters</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>.</p> +<h3 id="Integer_types"> Integer types</h3> <ul> +<li> +<code>short int</code> (also accessible as <code>short</code>, may use the keyword <code>signed</code>) </li> +<li> +<code>unsigned short int</code> (also accessible as <code>unsigned short</code>) </li> +<li> +<code>int</code> (also accessible as <code>signed int</code>) </li> +<li> +<code>unsigned int</code> (also accessible as <code>unsigned</code>), the unsigned counterpart of <code>int</code>, implementing modulo arithmetic. Suitable for bit manipulations. </li> +<li> +<code>long int</code> (also accessible as <code>long</code>) </li> +<li> +<code>unsigned long int</code> (also accessible as <code>unsigned long</code>) </li> +</ul> This is the most optimal integer type for the platform, and is guaranteed to be at least 16 bits. Most current systems use 32 bits (see Data models below). <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul> +<li> +<code>long long int</code> (also accessible as <code>long long</code>) </li> +<li> +<code>unsigned long long int</code> (also accessible as <code>unsigned long long</code>) </li> +</ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> <tr class="t-rev t-since-c23"> +<td> <ul> +<li> +<code>_BitInt(n)</code> (also accessible as <code>signed _BitInt(n)</code>), the bit-precise signed integer types (where <code>n</code> is replaced by an integer constant expression denoting the precise width (including the sign bit), that cannot be larger than <code>BITINT_MAXWIDTH</code> from <a href="../types/limits" title="c/types/limits"><code><limits.h></code></a>) </li> +<li> +<code>unsigned _BitInt(n)</code>, the bit-precise unsigned integer types (where <code>n</code> is replaced by an integer constant expression denoting the precise width, that cannot be larger than <code>BITINT_MAXWIDTH</code> from <a href="../types/limits" title="c/types/limits"><code><limits.h></code></a>) </li> +</ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <p>Note: as with all type specifiers, any order is permitted: <code>unsigned long long int</code> and <code>long int unsigned long</code> name the same type.</p> +<p>The following table summarizes all available integer types and their properties:</p> +<table class="wikitable"> <tr> <th rowspan="2"> Type specifier </th> <th rowspan="2"> Equivalent type </th> <th colspan="5"> Width in bits by data model </th> +</tr> <tr> <th> C standard </th> <th> LP32 </th> <th> ILP32 </th> <th> LLP64 </th> <th> LP64 </th> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">char</pre> </td> <td> <span class="kw4">char</span> </td> <td rowspan="3"> at least<br> <b>8</b> </td> <td rowspan="3"> <b>8</b> </td> <td rowspan="3"> <b>8</b> </td> <td rowspan="3"> <b>8</b> </td> <td rowspan="3"> <b>8</b> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed char</pre> </td> <td> <span class="kw4">signed</span> <span class="kw4">char</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned char</pre> </td> <td> <span class="kw4">unsigned</span> <span class="kw4">char</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">short</pre> </td> <td rowspan="4"> <span class="kw4">short</span> <span class="kw4">int</span> </td> <td rowspan="6"> at least<br> <b>16</b> </td> <td rowspan="6"> <b>16</b> </td> <td rowspan="6"> <b>16</b> </td> <td rowspan="6"> <b>16</b> </td> <td rowspan="6"> <b>16</b> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">short int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed short</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed short int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned short</pre> </td> <td rowspan="2"> <span class="kw4">unsigned</span> <span class="kw4">short</span> <span class="kw4">int</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned short int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">int</pre> </td> <td rowspan="3"> <span class="kw4">int</span> </td> <td rowspan="5"> at least<br> <b>16</b> </td> <td rowspan="5"> <b>16</b> </td> <td rowspan="5"> <b>32</b> </td> <td rowspan="5"> <b>32</b> </td> <td rowspan="5"> <b>32</b> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned</pre> </td> <td rowspan="2"> <span class="kw4">unsigned</span> <span class="kw4">int</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">long</pre> </td> <td rowspan="4"> <span class="kw4">long</span> <span class="kw4">int</span> </td> <td rowspan="6"> at least<br> <b>32</b> </td> <td rowspan="6"> <b>32</b> </td> <td rowspan="6"> <b>32</b> </td> <td rowspan="6"> <b>32</b> </td> <td rowspan="6"> <b>64</b> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">long int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed long</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed long int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned long</pre> </td> <td rowspan="2"> <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">int</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned long int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">long long</pre> </td> <td rowspan="4"> <span class="kw4">long</span> <span class="kw4">long</span> <span class="kw4">int</span><br> <span class="t-mark-rev t-since-c99">(C99)</span> </td> <td rowspan="6"> at least<br> <b>64</b> </td> <td rowspan="6"> <b>64</b> </td> <td rowspan="6"> <b>64</b> </td> <td rowspan="6"> <b>64</b> </td> <td rowspan="6"> <b>64</b> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">long long int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed long long</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">signed long long int</pre> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned long long</pre> </td> <td rowspan="2"> <span class="kw4">unsigned</span> <span class="kw4">long</span> <span class="kw4">long</span> <span class="kw4">int</span><br> <span class="t-mark-rev t-since-c99">(C99)</span> </td> +</tr> <tr> <td> <pre style="text-align:left; width:auto; margin-left:auto; margin-right:auto;" data-language="c">unsigned long long int</pre> </td> +</tr> +</table> <p>Besides the minimal bit counts, the C Standard guarantees that <code>1</code> == <code>sizeof(char)</code> ≤ <code>sizeof(short)</code> ≤ <code>sizeof(int)</code> ≤ <code>sizeof(long)</code> ≤ <code>sizeof(long long)</code>.</p> +<p>Note: this allows the extreme case in which <a href="https://en.wikipedia.org/wiki/byte" class="extiw" title="enwiki:byte">byte</a> are sized 64 bits, all types (including <code>char</code>) are 64 bits wide, and <code>sizeof</code> returns 1 for every type.</p> +<p>Note: integer arithmetic is defined differently for the signed and unsigned integer types. See <a href="operator_arithmetic" title="c/language/operator arithmetic">arithmetic operators</a>, in particular <a href="operator_arithmetic#Overflows" title="c/language/operator arithmetic">integer overflows</a>.</p> +<h4 id="Data_models"> Data models</h4> <p>The choices made by each implementation about the sizes of the fundamental types are collectively known as <i>data model</i>. Four data models found wide acceptance:</p> +<p>32 bit systems:</p> +<ul> +<li> +<b>LP32</b> or <b>2/4/4</b> (int is 16-bit, long and pointer are 32-bit) </li> +<ul><li> Win16 API </li></ul> +<li> +<b>ILP32</b> or <b>4/4/4</b> (int, long, and pointer are 32-bit); </li> +<ul> +<li> Win32 API </li> +<li> Unix and Unix-like systems (Linux, Mac OS X) </li> +</ul> +</ul> <p>64 bit systems:</p> +<ul> +<li> <b>LLP64</b> or <b>4/4/8</b> (int and long are 32-bit, pointer is 64-bit) </li> +<ul><li> Win64 API </li></ul> +<li> <b>LP64</b> or <b>4/8/8</b> (int is 32-bit, long and pointer are 64-bit) </li> +<ul><li> Unix and Unix-like systems (Linux, Mac OS X) </li></ul> +</ul> <p>Other models are very rare. For example, <b>ILP64</b> (<b>8/8/8</b>: int, long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g. Unicos on Cray).</p> +<p>Note that exact-width integer types are available in <a href="../types/integer" title="c/types/integer"><code><stdint.h></code></a> since C99.</p> +<h3 id="Real_floating_types"> Real floating types</h3> <p>C has three <span class="t-rev-inl t-since-c23"><span>or six</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> types for representing real floating-point values:</p> +<ul> +<li> +<code>float</code> - single precision floating-point type. Matches <a href="https://en.wikipedia.org/wiki/Single-precision_floating-point_format" class="extiw" title="enwiki:Single-precision floating-point format">IEEE-754 binary32 format</a> if supported. </li> +<li> +<code>double</code> - double precision floating-point type. Matches <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format" class="extiw" title="enwiki:Double-precision floating-point format">IEEE-754 binary64 format</a> if supported. </li> +<li> +<code>long double</code> - extended precision floating-point type. Matches <a href="https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format" class="extiw" title="enwiki:Quadruple-precision floating-point format">IEEE-754 binary128 format</a> if supported, otherwise matches <a href="https://en.wikipedia.org/wiki/Extended_precision" class="extiw" title="enwiki:Extended precision">IEEE-754 binary64-extended format</a> if supported, otherwise matches some non-IEEE-754 extended floating-point format as long as its precision is better than binary64 and range is at least as good as binary64, otherwise matches IEEE-754 binary64 format. <ul> +<li> binary128 format is used by some HP-UX, SPARC, MIPS, ARM64, and z/OS implementations. </li> +<li> The most well known IEEE-754 binary64-extended format is 80-bit x87 extended precision format. It is used by many x86 and x86-64 implementations (a notable exception is MSVC, which implements <code>long double</code> in the same format as <code>double</code>, i.e. binary64). </li> +</ul> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <dl> +<dd> If the implementation predefines the macro constant <code>__STDC_IEC_60559_DFP__</code>, the following decimal floating-point types are also supported. <ul> +<li> +<code>_Decimal32</code> - Represents <a href="https://en.wikipedia.org/wiki/decimal32_floating-point_format" class="extiw" title="enwiki:decimal32 floating-point format">IEEE-754 decimal32 format</a>. </li> +<li> +<code>_Decimal64</code> - Represents <a href="https://en.wikipedia.org/wiki/decimal64_floating-point_format" class="extiw" title="enwiki:decimal64 floating-point format">IEEE-754 decimal64 format</a>. </li> +<li> +<code>_Decimal128</code> - Represents <a href="https://en.wikipedia.org/wiki/decimal128_floating-point_format" class="extiw" title="enwiki:decimal128 floating-point format">IEEE-754 decimal128 format</a>. </li> +</ul> </dd> +<dd> Otherwise, these decimal floating-point types are not supported. </dd> +</dl> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <p>Floating-point types may support special values:</p> +<ul> +<li> <i>infinity</i> (positive and negative), see <a href="../numeric/math/infinity" title="c/numeric/math/INFINITY"><code>INFINITY</code></a> </li> +<li> the <i>negative zero</i>, <code>-0.0</code>. It compares equal to the positive zero, but is meaningful in some arithmetic operations, e.g. <code>1.0/0.0 == INFINITY</code>, but <code>1.0/-0.0 == -INFINITY</code>) </li> +<li> <i>not-a-number</i> (NaN), which does not compare equal with anything (including itself). Multiple bit patterns represent NaNs, see <code><a href="../numeric/math/nan" title="c/numeric/math/nan">nan</a></code>, <a href="../numeric/math/nan" title="c/numeric/math/NAN"><code>NAN</code></a>. Note that C takes no special notice of signaling NaNs (specified by IEEE-754), and treats all NaNs as quiet. </li> +</ul> <p>Real floating-point numbers may be used with <a href="operator_arithmetic" title="c/language/operator arithmetic">arithmetic operators</a> + - / * and various mathematical functions from <a href="../numeric/math" title="c/numeric/math"><code><math.h></code></a>. Both built-in operators and library functions may raise floating-point exceptions and set <code><a href="../error/errno" title="c/error/errno">errno</a></code> as described in <a href="../numeric/math/math_errhandling" title="c/numeric/math/math errhandling"><code>math_errhandling</code></a>.</p> +<p>Floating-point expressions may have greater range and precision than indicated by their types, see <code><a href="../types/limits/flt_eval_method" title="c/types/limits/FLT EVAL METHOD">FLT_EVAL_METHOD</a></code>. <a href="operator_assignment" title="c/language/operator assignment">Assignment</a>, <a href="return" title="c/language/return">return</a>, and <a href="cast" title="c/language/cast">cast</a> force the range and precision to the one associated with the declared type.</p> +<p>Floating-point expressions may also be <i>contracted</i>, that is, calculated as if all intermediate values have infinite range and precision, see <a href="../preprocessor/impl#Standard_pragmas" title="c/preprocessor/impl"><code> #pragma STDC FP_CONTRACT</code></a>.</p> +<p>Some operations on floating-point numbers are affected by and modify the state of <a href="../numeric/fenv" title="c/numeric/fenv">the floating-point environment</a> (most notably, the rounding direction).</p> +<p><a href="conversion" title="c/language/conversion">Implicit conversions</a> are defined between real floating types and integer, complex, and imaginary types.</p> +<p>See <a href="../types/limits#Limits_of_floating-point_types" title="c/types/limits">Limits of floating-point types</a> and the <a href="../numeric/math" title="c/numeric/math"><code><math.h></code></a> library for additional details, limits, and properties of the floating-point types.</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <h3 id="Complex_floating_types"> Complex floating types</h3> <p>Complex floating types model the mathematical <a href="https://en.wikipedia.org/wiki/complex_number" class="extiw" title="enwiki:complex number">complex number</a>, that is the numbers that can be written as a sum of a real number and a real number multiplied by the imaginary unit: a + bi</p> +<p>The three complex types are</p> +<ul> +<li> <code>float _Complex</code> (also available as <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +<li> <code>double _Complex</code> (also available as <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +<li> <code>long double _Complex</code> (also available as <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +</ul> <p>Note: as with all type specifiers, any order is permitted: <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, <code><a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a> <span class="kw4">long</span> <span class="kw4">double</span></code>, and even <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a> <span class="kw4">long</span></code> name the same type.</p> +<div class="c source-c"><pre data-language="c">#include <complex.h> +#include <stdio.h> + +int main(void) +{ + double complex z = 1 + 2*I; + z = 1 / z; + printf("1/(1.0+2.0i) = %.1f%+.1fi\n", creal(z), cimag(z)); +}</pre></div> <p>Output:</p> +<div class="text source-text"><pre data-language="c">1/(1.0+2.0i) = 0.2-0.4i</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <p>If the macro constant <code>__STDC_NO_COMPLEX__</code> is defined by the implementation, the complex types (as well as the library header <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a>) are not provided.</p> +</td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <p>Each complex type has the same <a href="object" title="c/language/object">object representation</a> and <a href="object" title="c/language/object">alignment requirements</a> as an <a href="array" title="c/language/array">array</a> of two elements of the corresponding real type (<code>float</code> for <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, <code>double</code> for <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, <code>long double</code> for <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>). The first element of the array holds the real part, and the second element of the array holds the imaginary component.</p> +<div class="c source-c"><pre data-language="c">float a[4] = {1, 2, 3, 4}; +float complex z1, z2; +memcpy(&z1, a, sizeof z1); // z1 becomes 1.0 + 2.0i +memcpy(&z2, a+2, sizeof z2); // z2 becomes 3.0 + 4.0i</pre></div> <p>Complex numbers may be used with <a href="operator_arithmetic" title="c/language/operator arithmetic">arithmetic operators</a> + - * and /, possibly mixed with imaginary and real numbers. There are many mathematical functions defined for complex numbers in <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a>. Both built-in operators and library functions may raise floating-point exceptions and set <code><a href="../error/errno" title="c/error/errno">errno</a></code> as described in <a href="../numeric/math/math_errhandling" title="c/numeric/math/math errhandling"><code>math_errhandling</code></a>.</p> +<p>Increment and decrement are not defined for complex types.</p> +<p>Relational operators are not defined for complex types (there is no notion of "less than"). <a href="conversion" title="c/language/conversion">Implicit conversions</a> are defined between complex types and other arithmetic types.</p> +<p>In order to support the one-infinity model of complex number arithmetic, C regards any complex value with at least one infinite part as an infinity even if its other part is a NaN, guarantees that all operators and functions honor basic properties of infinities and provides <code><a href="../numeric/complex/cproj" title="c/numeric/complex/cproj">cproj</a></code> to map all infinities to the canonical one (see <a href="operator_arithmetic" title="c/language/operator arithmetic">arithmetic operators</a> for the exact rules).</p> +<div class="c source-c"><pre data-language="c">#include <complex.h> +#include <math.h> +#include <stdio.h> + +int main(void) +{ + double complex 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 infinity + printf("%f%+f*i\n", creal(z), cimag(z)); + +// textbook formula would give +// cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN +// but C gives ±∞+i*nan + double complex y = cexp(INFINITY + I*NAN); + printf("%f%+f*i\n", creal(y), cimag(y)); +}</pre></div> <p>Possible output:</p> +<div class="text source-text"><pre data-language="c">inf+inf*i +inf+nan*i</pre></div> <p>C also treats multiple infinities so as to preserve directional information where possible, despite the inherent limitations of the Cartesian representation:</p> +<p>multiplying the imaginary unit by real infinity gives the correctly-signed imaginary infinity: i × ∞ = i∞. Also, i × (∞ – i∞) = ∞ + i∞ indicates the reasonable quadrant.</p> +<h3 id="Imaginary_floating_types"> Imaginary floating types</h3> <p>Imaginary floating types model the mathematical <a href="https://en.wikipedia.org/wiki/imaginary_numbers" class="extiw" title="enwiki:imaginary numbers">imaginary numbers</a>, that is numbers that can be written as a real number multiplied by the imaginary unit: bi The three imaginary types are</p> +<ul> +<li> <code>float _Imaginary</code> (also available as <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +<li> <code>double _Imaginary</code> (also available as <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +<li> <code>long double _Imaginary</code> (also available as <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> if <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a> is included) </li> +</ul> <p>Note: as with all type specifiers, any order is permitted: <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code>, <code><a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a> <span class="kw4">long</span> <span class="kw4">double</span></code>, and even <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a> <span class="kw4">long</span></code> name the same type.</p> +<div class="c source-c"><pre data-language="c">#include <complex.h> +#include <stdio.h> + +int main(void) +{ + double imaginary z = 3*I; + z = 1 / z; + printf("1/(3.0i) = %+.1fi\n", cimag(z)); +}</pre></div> <p>Output:</p> +<div class="text source-text"><pre data-language="c">1/(3.0i) = -0.3i</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-until-c11"> +<td> <p>An implementation that defines <code>__STDC_IEC_559_COMPLEX__</code> is recommended, but not required to support imaginary numbers. POSIX recommends checking if the macro <code><a href="../numeric/complex/imaginary_i" title="c/numeric/complex/Imaginary I">_Imaginary_I</a></code> is defined to identify imaginary number support.</p> +</td> <td><span class="t-mark-rev t-until-c11">(until C11)</span></td> +</tr> <tr class="t-rev t-since-c11"> +<td> <p>Imaginary numbers are supported if <span class="t-rev-inl t-until-c23"><span><code>__STDC_IEC_559_COMPLEX__</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>__STDC_IEC_60559_COMPLEX__</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> is defined.</p> +</td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <p>Each of the three imaginary types has the same <a href="object" title="c/language/object">object representation</a> and <a href="object" title="c/language/object">alignment requirement</a> as its <i>corresponding real type</i> (<code>float</code> for <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code>, <code>double</code> for <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code>, <code>long double</code> for <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code>).</p> +<p>Note: despite that, imaginary types are distinct and <a href="type#Compatible_types" title="c/language/type">not compatible</a> with their corresponding real types, which prohibits aliasing.</p> +<p>Imaginary numbers may be used with <a href="operator_arithmetic" title="c/language/operator arithmetic">arithmetic operators</a> + - * and /, possibly mixed with complex and real numbers. There are many mathematical functions defined for imaginary numbers in <a href="../numeric/complex" title="c/numeric/complex"><code><complex.h></code></a>. Both built-in operators and library functions may raise floating-point exceptions and set <code><a href="../error/errno" title="c/error/errno">errno</a></code> as described in <a href="../numeric/math/math_errhandling" title="c/numeric/math/math errhandling"><code>math_errhandling</code></a>.</p> +<p>Increment and decrement are not defined for imaginary types. <a href="conversion" title="c/language/conversion">Implicit conversions</a> are defined between imaginary types and other arithmetic types.</p> +<p>The imaginary numbers make it possible to express all complex numbers using the natural notation <code>x + I*y</code> (where <code>I</code> is defined as <code><a href="../numeric/complex/imaginary_i" title="c/numeric/complex/Imaginary I">_Imaginary_I</a></code>). Without imaginary types, certain special complex values cannot be created naturally. For example, if <code>I</code> is defined as <code><a href="../numeric/complex/complex_i" title="c/numeric/complex/Complex I">_Complex_I</a></code>, then writing <code>0.0 + I*INFINITY</code> gives NaN as the real part, and <code><a href="http://en.cppreference.com/w/c/numeric/complex/CMPLX"><span class="kw748">CMPLX</span></a><span class="br0">(</span><span class="nu16">0.0</span>, INFINITY<span class="br0">)</span></code> must be used instead. Same goes for the numbers with the negative zero imaginary component, which are meaningful when working with the library functions with branch cuts, such as <code><a href="../numeric/complex/csqrt" title="c/numeric/complex/csqrt">csqrt</a></code>: <code>1.0 - 0.0*I</code> results in the positive zero imaginary component if <code>I</code> is defined as <code><a href="../numeric/complex/complex_i" title="c/numeric/complex/Complex I">_Complex_I</a></code> and the negative zero imaginary part requires the use of <code><a href="../numeric/complex/cmplx" title="c/numeric/complex/CMPLX">CMPLX</a></code> or <code><a href="../numeric/complex/conj" title="c/numeric/complex/conj">conj</a></code>.</p> +<p>Imaginary types also simplify implementations; multiplication of an imaginary by a complex can be implemented straightforwardly with two multiplications if the imaginary types are supported, instead of four multiplications and two additions.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Keywords"> Keywords</h3> <ul> +<li> <a href="../keyword/bool" title="c/keyword/bool"><code>bool</code></a>, <a href="../keyword/true" title="c/keyword/true"><code>true</code></a>, <a href="../keyword/false" title="c/keyword/false"><code>false</code></a>, <a href="../keyword/char" title="c/keyword/char"><code>char</code></a>, <a href="../keyword/int" title="c/keyword/int"><code>int</code></a>, <a href="../keyword/short" title="c/keyword/short"><code>short</code></a>, <a href="../keyword/long" title="c/keyword/long"><code>long</code></a>, <a href="../keyword/signed" title="c/keyword/signed"><code>signed</code></a>, <a href="../keyword/unsigned" title="c/keyword/unsigned"><code>unsigned</code></a>, <a href="../keyword/float" title="c/keyword/float"><code>float</code></a>, <a href="../keyword/double" title="c/keyword/double"><code>double</code></a>. </li> +<li> <a href="../keyword/_bool" title="c/keyword/ Bool"><code>_Bool</code></a>, <a href="https://en.cppreference.com/mwiki/index.php?title=c/keyword/_BitInt&action=edit&redlink=1" class="new" title="c/keyword/ BitInt (page does not exist)"><code>_BitInt</code></a>, <a href="../keyword/_complex" title="c/keyword/ Complex"><code>_Complex</code></a>, <a href="../keyword/_imaginary" title="c/keyword/ Imaginary"><code>_Imaginary</code></a>, <a href="../keyword/_decimal32" title="c/keyword/ Decimal32"><code>_Decimal32</code></a>, <a href="../keyword/_decimal64" title="c/keyword/ Decimal64"><code>_Decimal64</code></a>, <a href="../keyword/_decimal128" title="c/keyword/ Decimal128"><code>_Decimal128</code></a>. </li> +</ul> <h3 id="Range_of_values"> Range of values</h3> <p>The following table provides a reference for the limits of common numeric representations.</p> +<p>Prior to C23, the C Standard allowed any signed integer representation, and the minimum guaranteed range of N-bit signed integers was from \(\scriptsize -(2^{N-1}-1)\)-(2<sup class="t-su">N-1</sup>-1) to \(\scriptsize +2^{N-1}-1\)+2<sup class="t-su">N-1</sup>-1 (e.g. <b>-127</b> to <b>127</b> for a signed 8-bit type), which corresponds to the limits of <a href="https://en.wikipedia.org/wiki/one%27s_complement" class="extiw" title="enwiki:one's complement">one's complement</a> or <a href="https://en.wikipedia.org/wiki/Signed_number_representations#Sign-and-magnitude_method" class="extiw" title="enwiki:Signed number representations">sign-and-magnitude</a>.</p> +<p>However, all popular data models (including all of ILP32, LP32, LP64, LLP64) and almost all C compilers use <a href="https://en.wikipedia.org/wiki/two%27s_complement" class="extiw" title="enwiki:two's complement">two's complement</a> representation (the only known exceptions are some compliers for UNISYS), and as of C23, it is the only representation allowed by the standard, with the guaranteed range from \(\scriptsize -2^{N-1}\)-2<sup class="t-su">N-1</sup> to \(\scriptsize +2^{N-1}-1\)+2<sup class="t-su">N-1</sup>-1 (e.g. <b>-128</b> to <b>127</b> for a signed 8-bit type).</p> +<table class="wikitable"> <tr> <th rowspan="2">Type </th> <th rowspan="2">Size in bits </th> <th rowspan="2">Format </th> <th colspan="2">Value range </th> +</tr> <tr> <th> Approximate </th> <th> Exact </th> +</tr> <tr> <th rowspan="4">character </th> <td rowspan="2">8 </td> <td>signed </td> <td> </td> <td> +<b>−128</b> to <b>127</b> </td> +</tr> <tr> <td>unsigned </td> <td> </td> <td> +<b>0</b> to <b>255</b> </td> +</tr> <tr> <td>16 </td> <td>UTF-16 </td> <td> </td> <td> +<b>0</b> to <b>65535</b> </td> +</tr> <tr> <td>32 </td> <td>UTF-32 </td> <td> </td> <td> +<b>0</b> to <b>1114111</b> (<b>0x10ffff</b>) </td> +</tr> <tr> <th rowspan="6">integer </th> <td rowspan="2">16 </td> <td>signed </td> <td> +<b>± 3.27 · 10<sup>4</sup></b> </td> <td> +<b>−32768</b> to <b>32767</b> </td> +</tr> <tr> <td>unsigned </td> <td> +<b>0</b> to <b>6.55 · 10<sup>4</sup></b> </td> <td> +<b>0</b> to <b>65535</b> </td> +</tr> <tr> <td rowspan="2">32 </td> <td>signed </td> <td> +<b>± 2.14 · 10<sup>9</sup></b> </td> <td> +<b>−2,147,483,648</b> to <b>2,147,483,647</b> </td> +</tr> <tr> <td>unsigned </td> <td> +<b>0</b> to <b>4.29 · 10<sup>9</sup></b> </td> <td> +<b>0</b> to <b>4,294,967,295</b> </td> +</tr> <tr> <td rowspan="2">64 </td> <td>signed </td> <td> +<b>± 9.22 · 10<sup>18</sup></b> </td> <td> +<b>−9,223,372,036,854,775,808</b> to <b>9,223,372,036,854,775,807</b> </td> +</tr> <tr> <td>unsigned </td> <td> +<b>0</b> to <b>1.84 · 10<sup>19</sup></b> </td> <td> +<b>0</b> to <b>18,446,744,073,709,551,615</b> </td> +</tr> <tr> <th rowspan="4">binary<br> floating<br> point </th> <td>32 </td> <td> +<a href="https://en.wikipedia.org/wiki/Single-precision_floating-point_format" class="extiw" title="enwiki:Single-precision floating-point format">IEEE-754</a> </td> <td> <ul> +<li>min subnormal:<br><b>± 1.401,298,4 · 10<sup>−45</sup></b> </li> +<li>min normal:<br><b>± 1.175,494,3 · 10<sup>−38</sup></b> </li> +<li>max:<br><b>± 3.402,823,4 · 10<sup>38</sup></b> </li> +</ul> </td> <td> <ul> +<li>min subnormal:<br><b>±0x1p−149</b> </li> +<li>min normal:<br><b>±0x1p−126</b> </li> +<li>max:<br><b>±0x1.fffffep+127</b> </li> +</ul> </td> +</tr> <tr> <td>64 </td> <td> +<a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format" class="extiw" title="enwiki:Double-precision floating-point format">IEEE-754</a> </td> <td> <ul> +<li>min subnormal:<br><b>± 4.940,656,458,412 · 10<sup>−324</sup></b> </li> +<li>min normal:<br><b>± 2.225,073,858,507,201,4 · 10<sup>−308</sup></b> </li> +<li>max:<br><b>± 1.797,693,134,862,315,7 · 10<sup>308</sup></b> </li> +</ul> </td> <td> <ul> +<li>min subnormal:<br><b>±0x1p−1074</b> </li> +<li>min normal:<br><b>±0x1p−1022</b> </li> +<li>max:<br><b>±0x1.fffffffffffffp+1023</b> </li> +</ul> </td> +</tr> <tr> <td>80<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[note 1]</a></sup> </td> <td> +<a href="https://en.wikipedia.org/wiki/Extended_precision" class="extiw" title="enwiki:Extended precision">x86</a> </td> <td> <ul> +<li>min subnormal:<br><b>± 3.645,199,531,882,474,602,528<br> · 10<sup>−4951</sup></b> </li> +<li>min normal:<br><b>± 3.362,103,143,112,093,506,263<br> · 10<sup>−4932</sup></b> </li> +<li>max:<br><b>± 1.189,731,495,357,231,765,021<br> · 10<sup>4932</sup></b> </li> +</ul> </td> <td> <ul> +<li>min subnormal:<br><b>±0x1p−16445</b> </li> +<li>min normal:<br><b>±0x1p−16382</b> </li> +<li>max:<br><b>±0x1.fffffffffffffffep+16383</b> </li> +</ul> </td> +</tr> <tr> <td>128 </td> <td> +<a href="https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format" class="extiw" title="enwiki:Quadruple-precision floating-point format">IEEE-754</a> </td> <td> <ul> +<li>min subnormal:<br><b>± 6.475,175,119,438,025,110,924,<br>438,958,227,646,552,5 · 10<sup>−4966</sup></b> </li> +<li>min normal:<br><b>± 3.362,103,143,112,093,506,262,<br>677,817,321,752,602,6 · 10<sup>−4932</sup></b> </li> +<li>max:<br><b>± 1.189,731,495,357,231,765,085,<br>759,326,628,007,016,2 · 10<sup>4932</sup></b> </li> +</ul> </td> <td> <ul> +<li>min subnormal:<br><b>±0x1p−16494</b> </li> +<li>min normal:<br><b>±0x1p−16382</b> </li> +<li>max:<br><b>±0x1.ffffffffffffffffffffffffffff<br>p+16383</b> </li> +</ul> </td> +</tr> <tr> <th rowspan="3"> decimal<br> floating<br> point </th> <td> 32 </td> <td> <a href="https://en.wikipedia.org/wiki/decimal32_floating-point_format" class="extiw" title="enwiki:decimal32 floating-point format">IEEE-754</a> </td> <td> </td> <td> <ul> +<li>min subnormal:<br><b>± 1 · 10<sup>-101</sup></b> </li> +<li>min normal:<br><b>± 1 · 10<sup>-95</sup></b> </li> +<li>max:<br><b>± 9.999'999 · 10<sup>96</sup></b> </li> +</ul> </td> +</tr> <tr> <td> 64 </td> <td> <a href="https://en.wikipedia.org/wiki/decimal64_floating-point_format" class="extiw" title="enwiki:decimal64 floating-point format">IEEE-754</a> </td> <td> </td> <td> <ul> +<li>min subnormal:<br><b>± 1 · 10<sup>-398</sup></b> </li> +<li>min normal:<br><b>± 1 · 10<sup>-383</sup></b> </li> +<li>max:<br><b>± 9.999'999'999'999'999 · 10<sup>384</sup></b> </li> +</ul> </td> +</tr> <tr> <td> 128 </td> <td> <a href="https://en.wikipedia.org/wiki/decimal128_floating-point_format" class="extiw" title="enwiki:decimal128 floating-point format">IEEE-754</a> </td> <td> </td> <td> <ul> +<li>min subnormal:<br><b>± 1 · 10<sup>-6176</sup></b> </li> +<li>min normal:<br><b>± 1 · 10<sup>-6143</sup></b> </li> +<li>max:<br><b>± 9.999'999'999'999'999'999'<br>999'999'999'999'999 · 10<sup>6144</sup></b> </li> +</ul> </td> +</tr> +</table> <ol class="references"> <li id="cite_note-1"> <span class="reference-text">The object representation usually occupies 96/128 bits on 32/64-bit platforms respectively.</span> </li> </ol> <p>Note: actual (as opposed to guaranteed minimal) ranges are available in the library headers <a href="../types/limits" title="c/types/limits"><code><limits.h></code></a> and <a href="../types/limits#Limits_of_floating_point_types" title="c/types/limits"><code><float.h></code></a>.</p> +<h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/types" title="cpp/language/types">C++ documentation</a></span> for <span class=""><span>Fundamental types</span></span> </td> +</tr> </table> <div class="_attribution"> + <p class="_attribution-p"> + © cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br> + <a href="https://en.cppreference.com/w/c/language/arithmetic_types" class="_attribution-link">https://en.cppreference.com/w/c/language/arithmetic_types</a> + </p> +</div> |
