文章目录
1. 前言
The GNU C Library Reference Manual for version 2.35
2. 算术函数
Arithmetic Functions
本章包含有关执行基本算术运算的函数的信息,例如将浮点数拆分为整数和小数部分或检索复数的虚数部分。这些函数在头文件 math.h 和 complex.h 中声明。
2.1. 整数
Integers
C 语言定义了几种整数数据类型:整数、短整数、长整数和字符,所有这些数据类型都有有符号和无符号两种。GNU C 编译器也扩展了该语言以包含 long long 整数。
C 整数类型旨在允许代码在具有不同固有数据大小(字长)的机器之间移植,因此每种类型在不同机器上可能具有不同的范围。这样做的问题是,通常需要为特定范围的整数编写程序,并且有时必须针对特定大小的存储空间编写程序,而不管程序在哪台机器上运行。
为了解决这个问题,GNU C 库包含 C 类型定义,您可以使用它来声明满足您确切需要的整数。因为 GNU C 库头文件是针对特定机器定制的,所以您的程序源代码不必如此。
这些 typedef 在 stdint.h 中。
如果您要求整数精确地用 N 位表示,请使用以下类型之一,并明显映射到位大小和符号:
- int8_t
- int16_t
- int32_t
- int64_t
- uint8_t
- uint16_t
- uint32_t
- uint64_t
如果您的 C 编译器和目标机器不允许特定大小的整数,则对应的上述类型不存在。
如果您不需要特定的存储大小,但想要具有至少 N 位的最小数据结构,请使用以下之一:
- int_least8_t
- int_least16_t
- int_least32_t
- int_least64_t
- uint_least8_t
- uint_least16_t
- uint_least32_t
- uint_least64_t
如果您不需要特定的存储大小,但想要允许最快访问同时至少具有 N 位的数据结构(并且在具有相同访问速度的数据结构中,最小的一个),请使用以下之一:
- int_fast8_t
- int_fast16_t
- int_fast32_t
- int_fast64_t
- uint_fast8_t
- uint_fast16_t
- uint_fast32_t
- uint_fast64_t
如果您想要一个在使用它的平台上具有最大范围的整数,请使用以下选项之一。如果你使用这些,你应该编写考虑到变量大小和整数范围的代码。
- intmax_t
- uintmax_t
GNU C 库还提供了告诉您每种整数数据类型的最大和最小可能值的宏。宏名称遵循以下示例:INT32_MAX、UINT8_MAX、INT_FAST32_MIN、INT_LEAST64_MIN、UINTMAX_MAX、INTMAX_MAX、INTMAX_MIN。请注意,无符号整数最小值没有宏。这些总是零。同样,这些类型的宽度也有 INTMAX_WIDTH 等宏。这些整数类型宽度的宏来自 TS 18661-1:2014。
有类似的宏可用于 C 的内置整数类型,这些宏应该随 C 编译器一起提供。这些在数据类型测量中进行了描述。
不要忘记,您可以将 C sizeof 函数与这些数据类型中的任何一种一起使用,以获取每种使用的存储字节数。
2.2. 整数除法
Integer Division
本节介绍执行整数除法的函数。当使用 GNU CC 时,这些函数是多余的,因为在 GNU C 中,“/”运算符总是向零舍入。但在其他 C 实现中,“/”可能会以不同的方式舍入否定参数。div 和 ldiv 很有用,因为它们指定如何将商:向零舍入。余数与分子的符号相同。
这些函数被指定返回一个结果 r,使得值 r.quot*denominator + r.rem 等于分子。
要使用这些工具,您应该在程序中包含头文件 stdlib.h。
数据类型:div_t
这是一种结构类型,用于保存 div 函数返回的结果。它有以下成员:
int quot
除法的商。
int rem
除法的余数。
函数:div_t div (int numerator, int denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
函数 div 计算分子除以分母的商和余数,并以 div_t 类型的结构返回结果。
如果结果无法表示(如除以零),则行为未定义。
这是一个示例,尽管不是很有用。
div_t result;
result = div (20, -6);
现在 result.quot 是 -3 而 result.rem 是 2。
数据类型:ldiv_t
这是一种结构类型,用于保存 ldiv 函数返回的结果。它有以下成员:
long int quot
除法的商。
long int rem
除法的余数。
(这与 div_t 相同,只是组件的类型为 long int 而不是 int。)
函数:ldiv_t ldiv (long int numerator, long int denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
ldiv 函数与 div 类似,不同之处在于参数是 long int 类型,并且结果作为 ldiv_t 类型的结构返回。
数据类型:lldiv_t
这是一种结构类型,用于保存 lldiv 函数返回的结果。它有以下成员:
long long int quot
除法的商。
long long int rem
除法的余数。
(这与 div_t 相同,只是组件的类型是 long long int 而不是 int。)
函数:lldiv_t lldiv (long long int numerator, long long int denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
lldiv 函数类似于 div 函数,但参数是 long long int 类型,结果作为 lldiv_t 类型的结构返回。
lldiv 函数是在 ISO C99 中添加的。
数据类型:imaxdiv_t
这是一种结构类型,用于保存 imaxdiv 函数返回的结果。它有以下成员:
intmax_t quot
除法的商。
intmax_t rem
除法的余数。
(这与 div_t 相同,只是组件的类型为 intmax_t 而不是 int。)
有关 intmax_t 类型的描述,请参见整数。
函数:imaxdiv_t imaxdiv (intmax_t numerator, intmax_t denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
imaxdiv 函数类似于 div 函数,但参数是 intmax_t 类型,结果作为 imaxdiv_t 类型的结构返回。
有关 intmax_t 类型的描述,请参见整数。
在 ISO C99 中添加了 imaxdiv 函数。
2.3. 浮点数
Floating Point Numbers
大多数计算机硬件都支持两种不同的数字:整数(…-3、-2、-1、0、1、2、3…)和浮点数。浮点数由三部分组成:尾数、指数和符号位。由浮点值表示的实数由 (s ? -1 : 1) · 2^e · M 给出,其中 s 是符号位,e 是指数,M 是尾数。有关详细信息,请参阅浮点表示概念。(指数可能有不同的基数,但所有现代硬件都使用 2。)
浮点数可以表示实数的有限子集。虽然这个子集对于大多数用途来说足够大,但重要的是要记住,唯一可以精确表示的实数是有理数,其终止二进制扩展比尾数的宽度短。即使是简单的分数,例如 1/5,也只能用浮点数来近似。
数学运算和函数经常需要产生不可表示的值。出于实际目的,这些值通常可以足够接近,但有时不能。从历史上看,没有办法判断计算结果何时不准确。现代计算机执行 IEEE 754 数值计算标准,该标准定义了一个框架,用于在计算结果不可信时向程序指示。该框架由一组异常组成,这些异常指示无法表示结果的原因,以及特殊值无穷大而不是数字 (NaN)。
2.4. 浮点数分类函数
Floating-Point Number Classification Functions
ISO C99 定义了允许您确定变量所包含的浮点数类型的宏。
宏:int fpclassify (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这是一个通用宏,适用于所有浮点类型,并返回一个 int 类型的值。可能的值是:
FP_NAN
浮点数 x 是“非数字”(参见 Infinity 和 NaN)
FP_INFINITE
x 的值是正无穷大或负无穷大(参见 Infinity 和 NaN)
FP_ZERO
x 的值为零。在 IEEE 754 等浮点格式中,可以对零进行符号化,如果 x 为负零,也会返回此值。
FP_SUBNORMAL
绝对值太小而无法以正常格式表示的数字以替代的非规范化格式表示(请参阅浮点表示概念)。这种格式不太精确,但可以表示接近零的值。fpclassify 以这种替代格式为 x 的值返回该值。
FP_NORMAL
为 x 的所有其他值返回此值。它表明该数字没有什么特别之处。
如果必须测试一个数字的多个属性,则 fpclassify 最有用。还有更具体的宏一次只测试一个属性。通常这些宏比 fpclassify 执行得更快,因为它们有特殊的硬件支持。因此,您应该尽可能使用特定的宏。
宏:int iscanonical (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
在某些浮点格式中,某些值具有规范(首选)和非规范编码(对于 IEEE 交换二进制格式,所有编码都是规范的)。如果 x 具有规范编码,则此宏返回非零值。它来自 TS 18661-1:2014。
请注意,某些格式具有多个值的编码,这些编码都同样规范;iscanonical 为所有此类编码返回一个非零值。此外,格式可能具有不对应于任何有效类型值的编码。在 ISO C 术语中,这些是陷阱表示;在 GNU C 库中,iscanonical 对此类编码返回零。
宏:int isfinite (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 是有限的,则此宏返回一个非零值:不是正无穷大或负无穷大,也不是 NaN。它相当于
(fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE)
isfinite 被实现为一个接受任何浮点类型的宏。
宏:int isnormal (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 是有限且归一化的,则此宏返回一个非零值。它相当于
(fpclassify (x) == FP_NORMAL)
宏:int isnan (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 为 NaN,则此宏返回非零值。它相当于
(fpclassify (x) == FP_NAN)
宏:int issignaling (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 是信号 NaN (sNaN),则此宏返回非零值。它来自 TS 18661-1:2014。
宏:int issubnormal (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 是次正规的,则此宏返回一个非零值。它来自 TS 18661-1:2014。
宏: int iszero (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 为零,此宏将返回一个非零值。它来自 TS 18661-1:2014。
BSD 提供了另一组浮点分类函数。GNU C 库也支持这些函数;但是,我们建议您在新代码中使用 ISO C99 宏。这些是标准的,将更广泛地使用。此外,由于它们是宏,因此您不必担心它们的参数类型。
函数:
int isinf (double x)
int isinff (float x)
int isinfl (long double x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 表示负无穷大,此函数返回 -1,如果 x 表示正无穷大,则返回 1,否则返回 0。
函数:
int isnan (double x)
int isnanf (float x)
int isnanl (long double x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 是“非数字”值,则此函数返回非零值,否则返回零。
注意:ISO C99 定义的 isnan 宏会覆盖 BSD 函数。这通常不是问题,因为这两个例程的行为相同。但是,如果你真的因为某种原因需要获取 BSD 功能,你可以写
(isnan) (x)
函数:
int finite (double x)
int finitef (float x)
int finitel (long double x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
如果 x 既不是无穷大也不是“非数字”值,则此函数返回一个非零值,否则返回零。
可移植性说明:本节列出的功能是 BSD 扩展。
2.5. 浮点计算中的错误
Errors in Floating-Point Calculations
2.5.1. FP 异常
FP Exceptions
IEEE 754 标准定义了计算期间可能发生的五种异常。每个都对应于一种特定类型的错误,例如溢出。
当异常发生时(当引发异常时,在标准的语言中),可能会发生以下两种情况之一。默认情况下,异常只是简单地在浮点状态字中注明,程序继续进行,就好像什么都没发生一样。该操作会产生一个默认值,该值取决于异常(见下表)。您的程序可以检查状态字以找出发生了哪些异常。
或者,您可以启用异常陷阱。在这种情况下,当引发异常时,您的程序将收到 SIGFPE 信号。此信号的默认操作是终止程序。请参阅信号处理,了解如何更改信号的效果。
IEEE 754 中定义的例外是:
‘Invalid Operation’
如果给定的操作数对于要执行的操作无效,则会引发此异常。例如(参见 IEEE 754,第 7 节):
- 加法或减法:∞ - ∞。(但 ∞ + ∞ = ∞)。
- 乘法:0·∞。
- 除法:0/0 或 ∞/∞。
- 余数:x REM y,其中 y 为零或 x 为无穷大。
- 如果操作数小于零,则平方根。更一般地,任何在其域之外评估的数学函数都会产生此异常。
- 当数字无法以目标格式表示时(由于溢出、无穷大或 NaN),将浮点数转换为整数或十进制字符串。
- 无法识别的输入字符串的转换。
- 当一个或另一个操作数是 NaN 时,通过涉及 < 或 > 的谓词进行比较。您可以改用无序比较函数来防止此异常;请参阅浮点比较函数。
如果异常没有捕获,则运算结果为 NaN。
‘Division by Zero’
当有限的非零数除以零时会引发此异常。如果没有发生陷阱,则结果为 +∞ 或 -∞,具体取决于操作数的符号。
‘Overflow’
只要结果不能以目标的精度格式表示为有限值,就会引发此异常。如果没有发生陷阱,则结果取决于中间结果的符号和当前的舍入模式(IEEE 754,第 7.3 节):
- 四舍五入将所有溢出带到∞,中间结果的符号。
- 向 0 舍入将所有溢出带到带有中间结果符号的最大可表示有限数。
- 向 -∞ 舍入会将正溢出带到最大可表示的有限数,将负溢出带到 -∞。
- 向 ∞ 舍入会将负溢出带到最负的可表示有限数,将正溢出带到 ∞。
每当引发溢出异常时,也会引发不精确异常。
‘Underflow’
当中间结果太小而无法准确计算,或者四舍五入到目标精度的运算结果太小而无法归一化时,就会引发下溢异常。
当没有为下溢异常安装陷阱时,只有在检测到微小和精度损失时才会发出下溢信号(通过下溢标志)。如果未安装陷阱处理程序,则操作以不精确的小值继续,如果目标精度不能保持小的精确结果,则操作为零。
‘Inexact’
如果舍入结果不准确(例如在计算 2 的平方根时)或结果溢出而没有溢出陷阱,则会发出此异常信号。
2.5.2. 无穷大和NaN
Infinity and NaN
IEEE 754 浮点数可以表示正无穷或负无穷,以及 NaN(不是数字)。这三个值来自结果未定义或无法准确表示的计算。您还可以故意为它们中的任何一个设置一个浮点变量,这有时很有用。产生无穷大或 NaN 的一些计算示例:
1/0 = ∞
log (0) = -∞
sqrt (-1) = NaN
当计算产生任何这些值时,也会发生异常;请参阅 FP 例外。
基本运算和数学函数都接受无穷大和 NaN 并产生合理的输出。正如人们所期望的那样,无穷大通过计算传播:例如,2 + ∞ = ∞,4/∞ = 0,atan (∞) = π/2。另一方面,NaN 会感染任何涉及它的计算。除非无论用什么实际值替换 NaN,计算都会产生相同的结果,否则结果就是 NaN。
在比较运算中,正无穷大于除自身和 NaN 之外的所有值,负无穷小于除自身和 NaN 之外的所有值。NaN 是无序的:它不等于、大于或小于任何东西,包括它自己。如果 x 的值为 NaN,则 x == x 为假。您可以使用它来测试一个值是否为 NaN,但测试 NaN 的推荐方法是使用 isnan 函数(请参阅浮点数分类函数)。此外,<、>、<= 和 >= 在应用于 NaN 时会引发异常。
math.h 定义了允许您将变量显式设置为无穷大或 NaN 的宏。
宏:float INFINITY
表示正无穷大的表达式。它等于 1.0 / 0.0 等数学运算产生的值。-INFINITY 表示负无穷大。
您可以通过将浮点值与此宏进行比较来测试它是否是无限的。但是,不建议这样做;您应该改用 isfinite 宏。请参阅浮点数分类函数。
这个宏是在 ISO C99 标准中引入的。
宏:float NAN
表示“非数字”值的表达式。这个宏是一个 GNU 扩展,仅在支持“非数字”值的机器上可用——也就是说,在所有支持 IEEE 浮点的机器上。
你可以使用‘#ifdef NAN’来测试机器是否支持NaN。(当然,您必须安排 GNU 扩展可见,例如通过定义 _GNU_SOURCE,然后您必须包含 math.h。)
宏:float SNANF
宏:double SNAN
宏:long double SNANL
宏:_FloatN SNANFN
宏:_FloatNx SNANFNx
这些由 TS 18661-1:2014 和 TS 18661-3:2015 定义的宏是用于信号 NaN 的常量表达式。
宏:int FE_SNANS_ALWAYS_SIGNAL
此宏由 TS 18661-1:2014 定义,在 fenv.h 中定义为 1,以指示具有信号 NaN 输入和浮点结果的函数和操作始终引发无效异常并返回安静的 NaN,即使在情况下 (例如 fmax、hypot 和 pow),其中安静的 NaN 输入可以产生非 NaN 结果。由于某些编译器优化可能无法正确处理信号 NaN,因此仅在启用了对信号 NaN 的编译器支持时才定义此宏。可以使用 GCC 选项 -fsignaling-nans 启用该支持。
IEEE 754 还允许另一个不寻常的值:负零。当您将一个正数除以负无穷大时,或者当负数结果小于表示限制时,会产生此值。
2.5.3. 检查 FPU 状态字
Examining the FPU status word
ISO C99 定义了查询和操作浮点状态字的函数。您可以在方便时使用这些函数来检查未捕获的异常,而不是在计算过程中担心它们。
这些常量代表各种 IEEE 754 异常。并非所有 FPU 都报告所有不同的异常。当且仅当您为其编译的 FPU 支持该异常时,才定义每个常量,因此您可以使用“#ifdef”测试 FPU 支持。它们在 fenv.h 中定义。
FE_INEXACT
不准确的例外。
FE_DIVBYZERO
除以零异常。
FE_UNDERFLOW
下溢异常。
FE_OVERFLOW
溢出异常。
FE_INVALID
无效异常。
宏 FE_ALL_EXCEPT 是 FP 实现支持的所有异常宏的按位或。
这些函数允许您清除异常标记、测试异常以及保存和恢复标记的异常集。
函数:int feclearexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe !posix | AC-Safe !posix | See POSIX Safety Concepts.
此函数清除由异常指示的所有受支持的异常标志。
如果操作成功,该函数返回零,否则返回非零值。
函数:int feraiseexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数引发异常指示的受支持异常。如果在 excepts 中设置了多个异常位,则引发异常的顺序是未定义的,除非在不精确 (FE_INEXACT) 之前引发上溢 (FE_OVERFLOW) 或下溢 (FE_UNDERFLOW)。无论是上溢还是下溢,也会引发不精确的异常,这也取决于实现。
如果操作成功,该函数返回零,否则返回非零值。
函数:int fesetexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数设置异常指示的受支持异常标志,例如 feraiseexcept,但不会导致启用陷阱。fesetexcept 来自 TS 18661-1:2014。
如果操作成功,该函数返回零,否则返回非零值。
函数:int fetestexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
测试当前是否设置了参数 except 所指示的异常标志。如果其中任何一个是,则返回一个非零值,该值指定设置了哪些异常。否则结果为零。
为了理解这些函数,假设状态字是一个名为 status 的整数变量。feclearexcept 等价于“status &= ~excepts”,而 fetestexcept 等价于“(status & excepts)”。当然,实际的实现可能会有很大的不同。
异常标志只有在程序明确请求时才会被清除,通过调用 feclearexcept。如果您想从一组计算中检查异常,您应该首先清除所有标志。下面是一个使用 fetestexcept 的简单示例:
{
double f;
int raised;
feclearexcept (FE_ALL_EXCEPT);
f = compute ();
raised = fetestexcept (FE_OVERFLOW | FE_INVALID);
if (raised & FE_OVERFLOW) { /* … */ }
if (raised & FE_INVALID) { /* … */ }
/* … */
}
您不能在状态字中显式设置位。但是,您可以保存整个状态字并在以后恢复它。这是通过以下功能完成的:
函数:int fegetexceptflag (fexcept_t *flagp, int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数在 flagp 指向的变量中存储一个实现定义的值,该值表示由 excepts 指示的异常标志的当前设置。
如果操作成功,该函数返回零,否则返回非零值。
函数:int fesetexceptflag (const fexcept_t *flagp, int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数将异常指示的异常标志恢复为存储在 flagp 指向的变量中的值。
如果操作成功,该函数返回零,否则返回非零值。
请注意,存储在 fexcept_t 中的值与 fetestexcept 返回的位掩码没有相似之处。该类型甚至可能不是整数。不要尝试修改 fexcept_t 变量。
函数:int fetestexceptflag (const fexcept_t *flagp, int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
测试 flagp 指向的变量中是否设置了参数 excepts 指示的异常标志。如果其中任何一个是,则返回一个非零值,该值指定设置了哪些异常。否则结果为零。fetestexceptflag 来自 TS 18661-1:2014。
2.5.4. 数学函数的错误报告
Error Reporting by Mathematical Functions
许多数学函数仅在实数或复数的子集上定义。即使它们是在数学上定义的,它们的结果也可能大于或小于它们的返回类型可表示的范围,而不会损失准确性。这些分别称为域错误、上溢和下溢。当这些错误之一发生时,数学函数会做几件事。在本手册中,我们将完整的响应称为域错误、上溢或下溢的信号。
当数学函数遇到域错误时,它会引发无效异常并返回 NaN。它还将 errno 设置为 EDOM;这是为了与不支持 IEEE 754 异常处理的旧系统兼容。同样,当发生溢出时,数学函数会引发溢出异常,并且在默认舍入模式下,酌情返回 ∞ 或 -∞(在其他舍入模式下,在适合该舍入模式时返回相应符号的最大有限值) .如果返回 ∞ 或 -∞,它们还将 errno 设置为 ERANGE;当溢出时返回有限值时,errno 可能会也可能不会设置为 ERANGE。当发生下溢时,将引发下溢异常,并根据函数的数学结果和舍入模式返回零(适当有符号)或次正规值。errno 可以设置为 ERANGE,但这不能保证;GNU C 库应该在下溢到适当的符号零时设置它,但不一定针对其他下溢。
当数学函数的参数是信号 NaN 时,GNU C 库不认为这是一个域错误,因此 errno 保持不变,但仍会引发无效异常(指定处理信号 NaN 的少数函数除外不同)。
一些数学函数在数学上定义为在其部分域上产生一个复数值。最熟悉的例子是取负数的平方根。在这种情况下,复杂的数学函数(例如 csqrt)将返回适当的复数值。实值函数(例如 sqrt)将发出域错误信号。
一些较旧的硬件不支持无穷大。在该硬件上,溢出会返回一个特定的非常大的数字(通常是最大的可表示数字)。math.h 定义了可用于测试新旧硬件溢出的宏。
宏:double HUGE_VAL
宏:float HUGE_VALF
宏:long double HUGE_VALL
宏:_FloatN HUGE_VAL_FN
宏:_FloatNx HUGE_VAL_FNx
表示特定非常大数字的表达式。在使用 IEEE 754 浮点格式的机器上,HUGE_VAL 是无穷大。在其他机器上,它通常是可以表示的最大正数。
当结果太大而无法表示时,数学函数会返回适当类型的 HUGE_VAL 或 -HUGE_VAL 版本。
2.6. 舍入模式
Rounding Modes
浮点计算在内部以额外的精度执行,然后四舍五入以适合目标类型。这可确保结果与输入数据一样精确。IEEE 754 定义了四种可能的舍入模式:
-
Round to nearest. 四舍五入到最近。
这是默认模式。除非对其他其中之一有特殊需要,否则应该使用它。在这种模式下,结果将四舍五入到最接近的可表示值。如果结果介于两个可表示值之间,则选择偶数可表示值。即使在这里也意味着最低位为零。这种舍入模式可防止统计偏差并保证数值稳定性:冗长计算中的舍入误差将保持小于 FLT_EPSILON 的一半。
-
Round toward plus Infinity. 向正无穷方向舍入。
所有结果都四舍五入到大于结果的最小可表示值。
-
Round toward minus Infinity. 向负无穷大舍入。
所有结果都四舍五入到小于结果的最大可表示值。
-
Round toward zero. 向零舍入。
所有结果都四舍五入到最大可表示值,其幅度小于结果的幅度。换句话说,如果结果为负,则向上取整;如果是正数,则向下舍入。
fenv.h 定义了可用于引用各种舍入模式的常量。当且仅当 FPU 支持相应的舍入模式时,才会定义每一个。
FE_TONEAREST
四舍五入到最近。
FE_UPWARD
向 +∞ 舍入。
FE_DOWNWARD
向 -∞ 舍入。
FE_TOWARDZERO
向零舍入。
下溢是一种不寻常的情况。通常,IEEE 754 浮点数总是被规范化(请参阅浮点表示概念)。小于 2^r 的数字(其中 r 是最小指数,FLT_MIN_RADIX-1 表示浮点数)不能表示为规范化数字。将所有这些数字四舍五入为零或 2^r 会导致某些算法在 0 处失败。因此,它们以非规范化形式保留。这会导致精度损失,因为尾数的某些位被盗以指示小数点。
如果结果太小而无法表示为非规范化数字,则将其四舍五入为零。但是,结果的符号被保留;如果计算为负,则结果为负零。负零也可能来自于无穷大的某些运算,例如 4/-∞。
在任何时候,都会选择上述四种舍入模式中的一种。您可以找出哪个具有此函数:
函数:int fegetround (void)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
返回当前选择的舍入模式,由定义的舍入模式宏的值之一表示。
要更改舍入模式,请使用此函数:
函数:int fesetround (int round)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将当前选定的舍入模式更改为舍入。如果 round 不对应于支持的舍入模式之一,则不会更改任何内容。如果更改舍入模式,fesetround 返回零,如果不支持该模式,则返回非零值。
如果可能,您应该避免更改舍入模式。这可能是一项昂贵的操作;此外,某些硬件要求您以不同的方式编译程序以使其工作。生成的代码可能会运行得更慢。有关详细信息,请参阅您的编译器文档。
2.7. 浮点控制函数
Floating-Point Control Functions
IEEE 754 浮点实现允许程序员通过设置控制字中的位来决定每个异常是否会发生陷阱。在 C 中,陷阱导致程序接收到 SIGFPE 信号;请参阅信号处理。
NB:IEEE 754 表示陷阱处理程序被赋予了异常情况的详细信息,并且可以设置结果值。C 信号不提供任何机制来来回传递此信息。因此,在 C 中捕获异常并不是很有用。
在执行某些计算时,有时需要保存浮点单元的状态。该库提供了保存和恢复异常标志、生成陷阱的异常集和舍入模式的函数。此信息称为浮点环境。
保存和恢复浮点环境的函数都使用 fenv_t 类型的变量来存储信息。这种类型在 fenv.h 中定义。它的大小和内容是实现定义的。您不应尝试直接操作此类型的变量。
要保存 FPU 的状态,请使用以下函数之一:
函数:int fegetenv (fenv_t *envp)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将浮点环境存储在 envp 指向的变量中。
如果操作成功,该函数返回零,否则返回非零值。
函数:int feholdexcept (fenv_t *envp)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将当前浮点环境存储在 envp 指向的对象中。然后清除所有异常标志,并将 FPU 设置为不捕获异常。并非所有 FPU 都支持捕获无异常;如果 feholdexcept 无法设置此模式,则返回非零值。如果成功,则返回零。
恢复浮点环境的函数可以采用以下类型的参数:
指向 fenv_t 对象的指针,这些对象之前通过调用 fegetenv 或 feholdexcept 进行了初始化。
特殊宏 FE_DFL_ENV 表示程序启动时可用的浮点环境。
实现定义的宏名称以 FE_ 开头,类型为 fenv_t *。
如果可能,GNU C 库定义了一个宏 FE_NOMASK_ENV,它代表了一个环境,在该环境中,引发的每个异常都会导致陷阱发生。您可以使用#ifdef 测试此宏。只有在定义了 _GNU_SOURCE 时才定义它。
某些平台可能会定义其他预定义环境。
要设置浮点环境,您可以使用以下任一函数:
函数:int fesetenv (const fenv_t *envp)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将浮点环境设置为 envp 所描述的环境。
如果操作成功,该函数返回零,否则返回非零值。
函数:int feupdateenv (const fenv_t *envp)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
与 fesetenv 一样,此函数将浮点环境设置为 envp 所描述的环境。但是,如果在调用 feupdateenv 之前在状态字中标记了任何异常,则在调用之后它们仍然被标记。也就是说,调用feupdateenv后,状态字就是前一个状态字和envp中保存的状态字的位或。
如果操作成功,该函数返回零,否则返回非零值。
TS 18661-1:2014 定义了额外的函数来保存和恢复浮点控制模式(例如舍入模式和是否启用陷阱),同时保持其他状态(例如引发的标志)不变。
特殊宏 FE_DFL_MODE 可以传递给 fesetmode。它代表程序启动时的浮点控制模式。
函数:int fegetmode (femode_t *modep)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将浮点控制模式存储在 modep 指向的变量中。
如果操作成功,该函数返回零,否则返回非零值。
函数:int fesetmode (const femode_t *modep)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
将浮点控制模式设置为 modep 所描述的模式。
如果操作成功,该函数返回零,否则返回非零值。
如果引发异常会导致陷阱发生,要控制个别异常,可以使用以下两个函数。
可移植性注意:这些函数都是 GNU 扩展。
函数:int feenableexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数为参数 excepts 指示的每个异常启用陷阱。检查 FPU 状态字中描述了各个异常。仅启用指定的异常,其他异常的状态不变。
如果操作成功,该函数返回先前启用的异常,否则返回-1。
函数:int fedisableexcept (int excepts)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数禁用每个异常的陷阱,如参数 excepts 所示。检查 FPU 状态字中描述了各个异常。只有指定的异常被禁用,其他异常的状态不变。
如果操作成功,该函数返回先前启用的异常,否则返回-1。
函数:int fegetexcept (void)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
该函数返回所有当前启用的异常的位掩码。如果失败,它会返回 -1。
2.8. 算术函数
Arithmetic Functions
C 库提供了对浮点数进行基本操作的函数。这些包括绝对值、最大值和最小值、归一化、位旋转、舍入和其他一些。
2.8.1. 绝对值
Absolute Value
提供这些函数用于获取数字的绝对值(或大小)。如果 x 为正,则实数 x 的绝对值为 x,如果 x 为负,则为 -x。对于复数 z,其实部为 x,虚部为 y,其绝对值为 sqrt (xx + yy)。
abs、labs 和 llabs 的原型在 stdlib.h 中;imaxabs 在 inttypes.h 中声明;fabs 函数在 math.h 中声明;cabs 函数在 complex.h 中声明。
函数:
int abs (int number)
long int labs (long int number)
long long int llabs (long long int number)
intmax_t imaxabs (intmax_t number)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回数字的绝对值。
大多数计算机使用二进制补码整数表示,其中无法表示 INT_MIN(可能的最小 int)的绝对值;因此,没有定义 abs (INT_MIN)。
llabs 和 imaxdiv 是 ISO C99 的新功能。
有关 intmax_t 类型的描述,请参见整数。
函数:
double fabs (double number)
float fabsf (float number)
long double fabsl (long double number)
_FloatN fabsfN (_FloatN number)
_FloatNx fabsfNx (_FloatNx number)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
该函数返回浮点数数字的绝对值。
函数:
double cabs (complex double z)
float cabsf (complex float z)
long double cabsl (complex long double z)
_FloatN cabsfN (complex _FloatN z)
_FloatNx cabsfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数 z 的绝对值(请参阅复数)。复数的绝对值为:
sqrt (creal (z) * creal (z) + cimag (z) * cimag (z))
应始终使用此函数而不是直接公式,因为它需要特别注意避免丢失精度。它还可以利用对该操作的硬件支持。请参阅幂和对数中的 hypot。
2.8.2. 归一化函数
Normalization Functions
本节中描述的函数主要是作为一种有效地对浮点数执行某些低级操作的方法,这些浮点数在内部使用二进制基数表示;请参阅浮点表示概念。即使表示不使用基数 2,这些函数也需要具有等效的行为,但当然它们在这些情况下不太可能特别有效。
所有这些函数都在 math.h 中声明。
函数:
double frexp (double value, int *exponent)
float frexpf (float value, int *exponent)
long double frexpl (long double value, int *exponent)
_FloatN frexpfN (_FloatN value, int *exponent)
_FloatNx frexpfNx (_FloatNx value, int *exponent)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数用于将数值拆分为归一化分数和指数。
如果参数值不为零,则返回值是 value 乘以 2 的幂,其大小始终在 1/2(包括)到 1(不包括)的范围内。对应的指数存储在*exponent;返回值乘以 2 得到这个指数等于原始数值。
例如,frexp (12.8, &exponent) 返回 0.8 并将 4 存储在指数中。
如果 value 为零,则返回值为零,并且零存储在 *exponent 中。
函数:
double ldexp (double value, int exponent)
float ldexpf (float value, int exponent)
long double ldexpl (long double value, int exponent)
_FloatN ldexpfN (_FloatN value, int exponent)
_FloatNx ldexpfNx (_FloatNx value, int exponent)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回浮点数值乘以 2 的幂指数的结果。(它可以用来重组被 frexp 拆开的浮点数。)
例如,ldexp (0.8, 4) 返回 12.8。
以下来自 BSD 的函数提供了与 ldexp 和 frexp 等效的功能。另请参阅最初也出现在 BSD 中的 ISO C 函数 logb。以下函数的 _FloatN 和 _FloatN 变体来自 TS 18661-3:2015。
函数:
double scalb (double value, double exponent)
float scalbf (float value, float exponent)
long double scalbl (long double value, long double exponent)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
scalb 函数是 ldexp 的 BSD 名称。
函数:
double scalbn (double x, int n)
float scalbnf (float x, int n)
long double scalbnl (long double x, int n)
_FloatN scalbnfN (_FloatN x, int n)
_FloatNx scalbnfNx (_FloatNx x, int n)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
scalbn 与 scalb 相同,只是指数 n 是 int 而不是浮点数。
函数:
double scalbln (double x, long int n)
float scalblnf (float x, long int n)
long double scalblnl (long double x, long int n)
_FloatN scalblnfN (_FloatN x, long int n)
_FloatNx scalblnfNx (_FloatNx x, long int n)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
scalbln 与 scalb 相同,只是指数 n 是 long int 而不是浮点数。
函数:
double significand (double x)
float significandf (float x)
long double significandl (long double x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
significand 返回缩放到范围 [1, 2) 的 x 的尾数。它等价于 scalb (x, (double) -ilogb (x))。
此功能主要用于某些 IEEE 754 一致性的标准化测试。
2.8.3. 舍入函数
Rounding Functions
此处列出的函数执行浮点值的舍入和截断等操作。其中一些函数将浮点数转换为整数值。它们都在 math.h 中声明。
您还可以将浮点数转换为整数,只需将它们转换为 int。这会丢弃小数部分,有效地向零舍入。但是,这只有在结果实际上可以表示为 int 时才有效——对于非常大的数字,这是不可能的。此处列出的函数将结果作为双精度返回来解决此问题。
fromfp 函数使用 TS 18661-1:2014 中的以下宏来指定舍入方向。这些对应于 IEEE 754-2008 中定义的舍入方向。
FP_INT_UPWARD
向 +∞ 舍入。
FP_INT_DOWNWARD
向 -∞ 舍入。
FP_INT_TOWARDZERO
向零舍入。
FP_INT_TONEARESTFROMZERO
四舍五入到最近,从零开始四舍五入。
FP_INT_TONEAREST
四舍五入到最近,平到平。
函数:
double ceil (double x)
float ceilf (float x)
long double ceill (long double x)
_FloatN ceilfN (_FloatN x)
_FloatNx ceilfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数将 x 向上舍入到最接近的整数,将该值作为双精度数返回。因此,ceil (1.5) 为 2.0。
函数:
double floor (double x)
float floorf (float x)
long double floorl (long double x)
_FloatN floorfN (_FloatN x)
_FloatNx floorfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数将 x 向下舍入到最接近的整数,并将该值作为双精度值返回。因此,地板 (1.5) 为 1.0,地板 (-1.5) 为 -2.0。
函数:
double trunc (double x)
float truncf (float x)
long double truncl (long double x)
_FloatN truncfN (_FloatN x)
_FloatNx truncfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
trunc 函数将 x 朝零舍入到最接近的整数(以浮点格式返回)。因此,trunc (1.5) 是 1.0,trunc (-1.5) 是 -1.0。
函数:
double rint (double x)
float rintf (float x)
long double rintl (long double x)
_FloatN rintfN (_FloatN x)
_FloatNx rintfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数根据当前舍入模式将 x 舍入为整数值。有关各种舍入模式的信息,请参阅浮点参数。默认的舍入模式是四舍五入到最接近的整数;有些机器支持其他模式,但除非您明确选择另一种,否则始终使用四舍五入。
如果 x 最初不是整数,则这些函数会引发不精确异常。
函数:
double nearbyint (double x)
float nearbyintf (float x)
long double nearbyintl (long double x)
_FloatN nearbyintfN (_FloatN x)
_FloatNx nearbyintfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回与 rint 函数相同的值,但如果 x 不是整数,则不会引发不精确异常。
函数:
double round (double x)
float roundf (float x)
long double roundl (long double x)
_FloatN roundfN (_FloatN x)
_FloatNx roundfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数类似于 rint,但它们从零而不是到最接近的整数(或其他当前舍入模式)舍入一半的情况。
函数:
double roundeven (double x)
float roundevenf (float x)
long double roundevenl (long double x)
_FloatN roundevenfN (_FloatN x)
_FloatNx roundevenfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些来自 TS 18661-1:2014 和 TS 18661-3:2015 的函数与 round 相似,但它们将中途情况舍入为偶数而不是远离零。
函数:
long int lrint (double x)
long int lrintf (float x)
long int lrintl (long double x)
long int lrintfN (_FloatN x)
long int lrintfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数就像 rint,但它们返回一个 long int 而不是浮点数。
函数:
long long int llrint (double x)
long long int llrintf (float x)
long long int llrintl (long double x)
long long int llrintfN (_FloatN x)
long long int llrintfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数就像 rint,但它们返回 long long int 而不是浮点数。
函数:
long int lround (double x)
long int lroundf (float x)
long int lroundl (long double x)
long int lroundfN (_FloatN x)
long int lroundfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数就像 round 一样,但它们返回一个 long int 而不是浮点数。
函数:
long long int llround (double x)
long long int llroundf (float x)
long long int llroundl (long double x)
long long int llroundfN (_FloatN x)
long long int llroundfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数就像 round 一样,但它们返回 long long int 而不是浮点数。
函数:
intmax_t fromfp (double x, int round, unsigned int width)
intmax_t fromfpf (float x, int round, unsigned int width)
intmax_t fromfpl (long double x, int round, unsigned int width)
intmax_t fromfpfN (_FloatN x, int round, unsigned int width)
intmax_t fromfpfNx (_FloatNx x, int round, unsigned int width)
uintmax_t ufromfp (double x, int round, unsigned int width)
uintmax_t ufromfpf (float x, int round, unsigned int width)
uintmax_t ufromfpl (long double x, int round, unsigned int width)
uintmax_t ufromfpfN (_FloatN x, int round, unsigned int width)
uintmax_t ufromfpfNx (_FloatNx x, int round, unsigned int width)
intmax_t fromfpx (double x, int round, unsigned int width)
intmax_t fromfpxf (float x, int round, unsigned int width)
intmax_t fromfpxl (long double x, int round, unsigned int width)
intmax_t fromfpxfN (_FloatN x, int round, unsigned int width)
intmax_t fromfpxfNx (_FloatNx x, int round, unsigned int width)
uintmax_t ufromfpx (double x, int round, unsigned int width)
uintmax_t ufromfpxf (float x, int round, unsigned int width)
uintmax_t ufromfpxl (long double x, int round, unsigned int width)
uintmax_t ufromfpxfN (_FloatN x, int round, unsigned int width)
uintmax_t ufromfpxfNx (_FloatNx x, int round, unsigned int width)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
TS 18661-1:2014 和 TS 18661-3:2015 中的这些函数根据舍入方向 round(FP_INT_* 宏之一)将浮点数转换为整数。如果整数超出有符号或无符号的范围(取决于函数的返回类型)的宽度宽度位类型(或超出返回类型的范围,如果宽度更大),或者如果 x 是无限的或 NaN ,或者如果宽度为零,则会发生域错误并返回未指定的值。当没有发生域错误并且参数不是整数时,名称中带有“x”的函数会引发不精确异常;其他函数不会引发不精确异常。
函数:
double modf (double value, double *integer-part)
float modff (float value, float *integer-part)
long double modfl (long double value, long double *integer-part)
_FloatN modffN (_FloatN value, _FloatN *integer-part)
_FloatNx modffNx (_FloatNx value, _FloatNx *integer-part)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数将参数值分成整数部分和小数部分(介于 -1 和 1 之间,不包括在内)。它们的总和等于价值。每个部分都与 value 具有相同的符号,并且整数部分始终向零舍入。
modf 将整数部分存储在 *integer-part 中,并返回小数部分。例如,modf (2.5, &intpart) 返回 0.5 并将 2.0 存储到 intpart。
2.8.4. 余数函数
Remainder Functions
本节中的函数计算两个浮点数相除的余数。每个都有点不同;选择一个适合您的问题。
函数:
double fmod (double numerator, double denominator)
float fmodf (float numerator, float denominator)
long double fmodl (long double numerator, long double denominator)
_FloatN fmodfN (_FloatN numerator, _FloatN denominator)
_FloatNx fmodfNx (_FloatNx numerator, _FloatNx denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数计算分子除以分母的余数。具体来说,返回值为分子 - n * 分母,其中 n 是分子除以分母的商,向零舍入为整数。因此,fmod (6.5, 2.3) 返回 1.9,即 6.5 减去 4.6。
结果与分子的符号相同,并且大小小于分母的大小。
如果分母为零,则 fmod 发出域错误信号。
函数:
double remainder (double numerator, double denominator)
float remainderf (float numerator, float denominator)
long double remainderl (long double numerator, long double denominator)
_FloatN remainderfN (_FloatN numerator, _FloatN denominator)
_FloatNx remainderfNx (_FloatNx numerator, _FloatNx denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数与 fmod 类似,只是它们将内商 n 舍入到最接近的整数,而不是向零舍入到整数。例如,余数 (6.5, 2.3) 返回 -0.4,即 6.5 减去 6.9。
结果的绝对值小于或等于分母绝对值的一半。fmod(分子、分母)和余数(分子、分母)之间的差值始终为分母、负分母或零。
如果分母为零,则余数表示域错误。
函数:
double drem (double numerator, double denominator)
float dremf (float numerator, float denominator)
long double dreml (long double numerator, long double denominator)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数是剩余部分的另一个名称。
2.8.5. 设置和修改单个 FP 值
Setting and modifying single bits of FP values
有些操作过于复杂或昂贵,无法手动对浮点数执行。ISO C99 定义了执行这些操作的函数,其中主要涉及更改单个位。
函数:
double copysign (double x, double y)
float copysignf (float x, float y)
long double copysignl (long double x, long double y)
_FloatN copysignfN (_FloatN x, _FloatN y)
_FloatNx copysignfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回 x 但带有 y 的符号。即使 x 或 y 为 NaN 或零,它们也能正常工作。这两个都可以带有符号(尽管并非所有实现都支持它),这是少数可以区分的操作之一。
copysign 从不引发异常。
此功能在 IEC 559 中定义(以及 IEEE 754/IEEE 854 中推荐功能的附录)。
函数:int signbit (float-type x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
signbit 是一个通用宏,可以处理所有浮点类型。如果 x 的值设置了符号位,则返回非零值。
这与 x < 0.0 不同,因为 IEEE 754 浮点允许对零进行签名。比较 -0.0 < 0.0 为假,但符号位 (-0.0) 将返回非零值。
函数:
double nextafter (double x, double y)
float nextafterf (float x, float y)
long double nextafterl (long double x, long double y)
_FloatN nextafterfN (_FloatN x, _FloatN y)
_FloatNx nextafterfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
nextafter 函数返回 x 在朝向 y 的方向上的下一个可表示邻居。x 和结果之间的步长大小取决于结果的类型。如果 x = y,该函数只返回 y。如果任一值为 NaN,则返回 NaN。否则,取决于方向,添加或减去对应于尾数中最低有效位的值的值。如果结果超出规范化数字的范围,nextafter 将发出溢出或下溢信号。
此功能在 IEC 559 中定义(以及 IEEE 754/IEEE 854 中推荐功能的附录)。
函数:
double nexttoward (double x, long double y)
float nexttowardf (float x, long double y)
long double nexttowardl (long double x, long double y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数与对应版本的 nextafter 相同,只是它们的第二个参数是 long double。
函数:
double nextup (double x)
float nextupf (float x)
long double nextupl (long double x)
_FloatN nextupfN (_FloatN x)
_FloatNx nextupfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
nextup 函数返回 x 在正无穷方向上的下一个可表示邻居。如果 x 是 x 类型中最小的负次正规数,则函数返回 -0。如果 x = 0,则函数返回 x 类型中最小的正次正规数。如果 x 是 NaN,则返回 NaN。如果 x 为 +∞,则返回 +∞。nextup 来自 TS 18661-1:2014 和 TS 18661-3:2015。nextup 永远不会引发异常,除非发出 NaN 信号。
函数:
double nextdown (double x)
float nextdownf (float x)
long double nextdownl (long double x)
_FloatN nextdownfN (_FloatN x)
_FloatNx nextdownfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
nextdown 函数返回 x 在负无穷方向上的下一个可表示邻居。如果 x 是 x 类型中最小的正次正规数,则函数返回 +0。如果 x = 0,则函数返回 x 类型中最小的负次正规数。如果 x 是 NaN,则返回 NaN。如果 x 为 -∞,则返回 -∞。nextdown 来自 TS 18661-1:2014 和 TS 18661-3:2015。nextdown 不会引发异常,除非发出 NaN 信号。
函数:
double nan (const char *tagp)
float nanf (const char *tagp)
long double nanl (const char *tagp)
_FloatN nanfN (const char *tagp)
_FloatNx nanfNx (const char *tagp)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
nan 函数返回 NaN 的表示形式,前提是目标平台支持 NaN。nan (“n-char-sequence”) 等价于 strtod (“NAN(n-char-sequence)”)。
参数 tagp 以未指定的方式使用。在 IEEE 754 系统上,NaN 有多种表示,tagp 选择其中一种。在其他系统上,它可能什么都不做。
函数:
int canonicalize (double *cx, const double *x)
int canonicalizef (float *cx, const float *x)
int canonicalizel (long double *cx, const long double *x)
int canonicalizefN (_FloatN *cx, const _FloatN *x)
int canonicalizefNx (_FloatNx *cx, const _FloatNx *x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
在某些浮点格式中,某些值具有规范(首选)和非规范编码(对于 IEEE 交换二进制格式,所有编码都是规范的)。这些函数由 TS 18661-1:2014 和 TS 18661-3:2015 定义,试图生成 x 指向的浮点值的规范版本;如果该值是信号 NaN,它们会引发无效异常并产生安静的 NaN。如果产生了规范值,则将其存储在 cx 指向的对象中,并且这些函数返回零。否则(如果由于 x 指向的对象不是任何浮点值的有效表示而无法生成规范值),则 cx 指向的对象不变并返回非零值。
请注意,某些格式具有多个值的编码,这些编码都同样规范;当这种编码用作此函数的输入时,任何相同值(或相应安静 NaN,如果该值是信号 NaN)的编码都可以作为输出产生。
函数:
double getpayload (const double *x)
float getpayloadf (const float *x)
long double getpayloadl (const long double *x)
_FloatN getpayloadfN (const _FloatN *x)
_FloatNx getpayloadfNx (const _FloatNx *x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
IEEE 754 将 NaN 的有效负载定义为以 NaN 表示形式编码的整数值。有效载荷通常从 NaN 输入传播到浮点运算的结果。这些函数由 TS 18661-1:2014 和 TS 18661-3:2015 定义,返回 x 指向的 NaN 的有效负载(返回为正整数,或正零,表示为浮点数);如果 x 不是 NaN,则返回 -1。即使对于信号 NaN,它们也不会引发浮点异常。(非 NaN 的参数的返回值 -1 在 C2x 中指定;该值在 TS 18661 中未指定。)
函数:
int setpayload (double *x, double payload)
int setpayloadf (float *x, float payload)
int setpayloadl (long double *x, long double payload)
int setpayloadfN (_FloatN *x, _FloatN payload)
int setpayloadfNx (_FloatNx *x, _FloatNx payload)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数由 TS 18661-1:2014 和 TS 18661-3:2015 定义,将 x 指向的对象设置为具有有效负载负载和零符号位的安静 NaN 并返回零。如果有效载荷不是一个正符号整数,它是给定类型的安静 NaN 的有效有效载荷,则 x 指向的对象设置为正零并返回一个非零值。它们不会引发浮点异常。
函数:
int setpayloadsig (double *x, double payload)
int setpayloadsigf (float *x, float payload)
int setpayloadsigl (long double *x, long double payload)
int setpayloadsigfN (_FloatN *x, _FloatN payload)
int setpayloadsigfNx (_FloatNx *x, _FloatNx payload)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数由 TS 18661-1:2014 和 TS 18661-3:2015 定义,将 x 指向的对象设置为带有有效负载和零符号位的信令 NaN 并返回零。如果有效载荷不是一个正符号整数,它是给定类型的信号 NaN 的有效有效载荷,则 x 指向的对象设置为正零并返回一个非零值。它们不会引发浮点异常。
2.8.6. 浮点比较函数
Floating-Point Comparison Functions
当一个或另一个操作数是 NaN 时,标准 C 比较运算符会引发异常。例如,
int v = a < 1.0;
如果 a 为 NaN,将引发异常。(这不会发生在 == 和 != 中;当检查 NaN 时,它们只会分别返回 false 和 true。)这种异常通常是不可取的。因此,ISO C99 定义了在检查 NaN 时不会引发异常的比较函数。所有的函数都实现为宏,允许它们的参数是任何浮点类型。保证宏只对它们的参数求值一次。TS 18661-1:2014 为相等比较添加了这样一个宏,它确实引发了 NaN 参数的异常;它还添加了对所有浮点值(包括 NaN)提供总排序的函数,即使对信号 NaN 也不会引发任何异常。
宏:int isgreater (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定参数 x 是否大于 y。它等价于 (x) > (y),但如果 x 或 y 为 NaN,则不会引发异常。
宏:int isgreaterequal (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定参数 x 是否大于或等于 y。它等价于 (x) >= (y),但如果 x 或 y 为 NaN,则不会引发异常。
宏:int isless (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定参数 x 是否小于 y。它等价于 (x) < (y),但如果 x 或 y 为 NaN,则不会引发异常。
宏:int islessequal (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定参数 x 是否小于或等于 y。它等价于 (x) <= (y),但如果 x 或 y 为 NaN,则不会引发异常。
宏:int islessgreater (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定参数 x 是小于还是大于 y。相当于 (x) < (y) || (x) > (y) (尽管它只计算 x 和 y 一次),但如果 x 或 y 为 NaN,则不会引发异常。
此宏不等同于 x != y,因为如果 x 或 y 为 NaN,则该表达式为真。
宏:int isunordered (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定其参数是否无序。换句话说,如果 x 或 y 为 NaN,则为真,否则为假。
宏:int iseqsig (real-floating x, real-floating y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此宏确定其参数是否相等。它等价于 (x) == (y),但如果任一参数为 NaN,则会引发无效异常并将 errno 设置为 EDOM。
函数:
int totalorder (const double *x, const double *y)
int totalorderf (const float *x, const float *y)
int totalorderl (const long double *x, const long double *y)
int totalorderfN (const _FloatN *x, const _FloatN *y)
int totalorderfNx (const _FloatNx *x, const _FloatNx *y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数确定 IEEE 754-2008 中定义的总顺序关系对于 *x 和 *y 是否为真,如果为真则返回非零,如果为假则返回零。即使是信号 NaN 也不会引发异常。如果它们是相同的浮点值(包括零和 NaN 的符号,以及 NaN 的有效负载),或者如果 *x 按以下顺序位于 *y 之前,则该关系为真:负安静 NaN,按有效负载递减的顺序;负信号 NaN,按有效载荷递减的顺序;负无穷大;有限数,按升序排列,负零在正零之前;正无穷大;正向信令 NaN,按有效载荷递增的顺序;正安静的 NaN,以增加有效载荷的顺序。
函数:
int totalordermag (const double *x, const double *y)
int totalordermagf (const float *x, const float *y)
int totalordermagl (const long double *x, const long double *y)
int totalordermagfN (const _FloatN *x, const _FloatN *y)
int totalordermagfNx (const _FloatNx *x, const _FloatNx *y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数确定 IEEE 754-2008 中定义的总顺序关系对于 *x 和 *y 的绝对值是否为真,如果为真则返回非零,如果为假则返回零。即使是信号 NaN 也不会引发异常。
并非所有机器都为这些操作提供硬件支持。在没有的机器上,宏可能会非常慢。因此,当 NaN 不是问题时,您不应使用这些函数。
注意:没有宏 isequal 或 isunequal。它们是不必要的,因为 == 和 != 运算符在其中一个或两个操作数为 NaN 时不会引发异常。
2.8.7. 其他 FP 算术函数
Miscellaneous FP arithmetic functions
本节中的函数执行杂项但常见的操作,这些操作很难用 C 运算符表示。在某些处理器上,这些函数可以使用特殊的机器指令来比等效的 C 代码更快地执行这些操作。
函数:
double fmin (double x, double y)
float fminf (float x, float y)
long double fminl (long double x, long double y)
_FloatN fminfN (_FloatN x, _FloatN y)
_FloatNx fminfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fmin 函数返回 x 和 y 两个值中较小的一个。它类似于表达式
((x) < (y) ? (x) : (y))
除了 x 和 y 只计算一次。
如果一个参数是安静的 NaN,则返回另一个参数。如果两个参数都是 NaN,或者其中一个是信号 NaN,则返回 NaN。
函数:
double fmax (double x, double y)
float fmaxf (float x, float y)
long double fmaxl (long double x, long double y)
_FloatN fmaxfN (_FloatN x, _FloatN y)
_FloatNx fmaxfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fmax 函数返回 x 和 y 两个值中的较大者。
如果一个参数是安静的 NaN,则返回另一个参数。如果两个参数都是 NaN,或者其中一个是信号 NaN,则返回 NaN。
函数:
double fminimum (double x, double y)
float fminimumf (float x, float y)
long double fminimuml (long double x, long double y)
_FloatN fminimumfN (_FloatN x, _FloatN y)
_FloatNx fminimumfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fminimum 函数返回 x 和 y 两个值中较小的一个。与 fmin 不同,如果任一参数是 NaN,则返回 NaN。正零被视为大于负零。
函数:
double fmaximum (double x, double y)
float fmaximumf (float x, float y)
long double fmaximuml (long double x, long double y)
_FloatN fmaximumfN (_FloatN x, _FloatN y)
_FloatNx fmaximumfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fmaximum 函数返回 x 和 y 两个值中的较大者。与 fmax 不同,如果任一参数是 NaN,则返回 NaN。正零被视为大于负零。
函数:
double fminimum_num (double x, double y)
float fminimum_numf (float x, float y)
long double fminimum_numl (long double x, long double y)
_FloatN fminimum_numfN (_FloatN x, _FloatN y)
_FloatNx fminimum_numfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fminimum_num 函数返回 x 和 y 两个值中较小的一个。如果一个参数是数字而另一个是 NaN,即使是信号 NaN,也会返回该数字。正零被视为大于负零。
函数:
double fmaximum_num (double x, double y)
float fmaximum_numf (float x, float y)
long double fmaximum_numl (long double x, long double y)
_FloatN fmaximum_numfN (_FloatN x, _FloatN y)
_FloatNx fmaximum_numfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fmaximum_num 函数返回 x 和 y 两个值中的较大者。如果一个参数是数字而另一个是 NaN,即使是信号 NaN,也会返回该数字。正零被视为大于负零。
函数:
double fminmag (double x, double y)
float fminmagf (float x, float y)
long double fminmagl (long double x, long double y)
_FloatN fminmagfN (_FloatN x, _FloatN y)
_FloatNx fminmagfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数(来自 TS 18661-1:2014 和 TS 18661-3:2015)返回 x 和 y 两个值中绝对值较小的那个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fmin 函数相同。
函数:
double fmaxmag (double x, double y)
float fmaxmagf (float x, float y)
long double fmaxmagl (long double x, long double y)
_FloatN fmaxmagfN (_FloatN x, _FloatN y)
_FloatNx fmaxmagfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数(来自 TS 18661-1:2014)返回两个值 x 和 y 中具有较大绝对值的任何一个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fmax 函数相同。
函数:
double fminimum_mag (double x, double y)
float fminimum_magf (float x, float y)
long double fminimum_magl (long double x, long double y)
_FloatN fminimum_magfN (_FloatN x, _FloatN y)
_FloatNx fminimum_magfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回 x 和 y 两个值中绝对值较小的那个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fminimum 函数相同。
函数:
double fmaximum_mag (double x, double y)
float fmaximum_magf (float x, float y)
long double fmaximum_magl (long double x, long double y)
_FloatN fmaximum_magfN (_FloatN x, _FloatN y)
_FloatNx fmaximum_magfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回两个值 x 和 y 中具有较大绝对值的那个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fmaximum 函数相同。
函数:
double fminimum_mag_num (double x, double y)
float fminimum_mag_numf (float x, float y)
long double fminimum_mag_numl (long double x, long double y)
_FloatN fminimum_mag_numfN (_FloatN x, _FloatN y)
_FloatNx fminimum_mag_numfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回 x 和 y 两个值中绝对值较小的那个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fminimum_num 函数相同。
函数:
double fmaximum_mag_num (double x, double y)
float fmaximum_mag_numf (float x, float y)
long double fmaximum_mag_numl (long double x, long double y)
_FloatN fmaximum_mag_numfN (_FloatN x, _FloatN y)
_FloatNx fmaximum_mag_numfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回两个值 x 和 y 中具有较大绝对值的那个。如果两者具有相同的绝对值,或者其中一个是 NaN,则它们的行为与 fmaximum_num 函数相同。
函数:
double fdim (double x, double y)
float fdimf (float x, float y)
long double fdiml (long double x, long double y)
_FloatN fdimfN (_FloatN x, _FloatN y)
_FloatNx fdimfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fdim 函数返回 x 和 y 之间的正差。如果 x 大于 y,则正差为 x - y,否则为 0。
如果 x、y 或两者都是 NaN,则返回 NaN。
函数:
double fma (double x, double y, double z)
float fmaf (float x, float y, float z)
long double fmal (long double x, long double y, long double z)
_FloatN fmafN (_FloatN x, _FloatN y, _FloatN z)
_FloatNx fmafNx (_FloatNx x, _FloatNx y, _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fma 函数执行浮点乘加。这是操作 (x · y) + z,但中间结果没有四舍五入到目标类型。这有时可以提高计算的精度。
引入此功能是因为某些处理器具有执行乘加的特殊指令。C 编译器不能直接使用它,因为定义了表达式‘x*y + z’来舍入中间结果。fma 允许您选择何时只想舍入一次。
在未在硬件中实现乘加的处理器上,fma 可能非常慢,因为它必须避免中间舍入。当 fma 的相应版本不低于表达式‘x*y + z’时,math.h 定义了符号 FP_FAST_FMA、FP_FAST_FMAF 和 FP_FAST_FMAL。在 GNU C 库中,这总是意味着操作是在硬件中实现的。
函数:
float fadd (double x, double y)
float faddl (long double x, long double y)
double daddl (long double x, long double y)
_FloatM fMaddfN (_FloatN x, _FloatN y)
_FloatM fMaddfNx (_FloatNx x, _FloatNx y)
_FloatMx fMxaddfN (_FloatN x, _FloatN y)
_FloatMx fMxaddfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
从 TS 18661-1:2014 和 TS 18661-3:2015 开始,这些函数返回 x + y,四舍五入到函数的返回类型,而没有对参数类型进行任何中间舍入。
函数:
float fsub (double x, double y)
float fsubl (long double x, long double y)
double dsubl (long double x, long double y)
_FloatM fMsubfN (_FloatN x, _FloatN y)
_FloatM fMsubfNx (_FloatNx x, _FloatNx y)
_FloatMx fMxsubfN (_FloatN x, _FloatN y)
_FloatMx fMxsubfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数(从 TS 18661-1:2014 和 TS 18661-3:2015 开始)返回 x - y,四舍五入到函数的返回类型,而不对参数类型进行任何中间舍入。
函数:
float fmul (double x, double y)
float fmull (long double x, long double y)
double dmull (long double x, long double y)
_FloatM fMmulfN (_FloatN x, _FloatN y)
_FloatM fMmulfNx (_FloatNx x, _FloatNx y)
_FloatMx fMxmulfN (_FloatN x, _FloatN y)
_FloatMx fMxmulfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数(来自 TS 18661-1:2014 和 TS 18661-3:2015)返回 x * y,四舍五入到函数的返回类型,而没有任何中间舍入到参数的类型。
函数:
float fdiv (double x, double y)
float fdivl (long double x, long double y)
double ddivl (long double x, long double y)
_FloatM fMdivfN (_FloatN x, _FloatN y)
_FloatM fMdivfNx (_FloatNx x, _FloatNx y)
_FloatMx fMxdivfN (_FloatN x, _FloatN y)
_FloatMx fMxdivfNx (_FloatNx x, _FloatNx y)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数,来自 TS 18661-1:2014 和 TS 18661-3:2015,返回 x / y,四舍五入到函数的返回类型,没有任何中间四舍五入到参数的类型。
函数:
float fsqrt (double x)
float fsqrtl (long double x)
double dsqrtl (long double x)
_FloatM fMsqrtfN (_FloatN x)
_FloatM fMsqrtfNx (_FloatNx x)
_FloatMx fMxsqrtfN (_FloatN x)
_FloatMx fMxsqrtfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数(来自 TS 18661-1:2014 和 TS 18661-3:2015)返回 x 的平方根,四舍五入到函数的返回类型,而没有任何中间舍入到参数的类型。
函数:
float ffma (double x, double y, double z)
float ffmal (long double x, long double y, long double z)
double dfmal (long double x, long double y, long double z)
_FloatM fMfmafN (_FloatN x, _FloatN y, _FloatN z)
_FloatM fMfmafNx (_FloatNx x, _FloatNx y, _FloatNx z)
_FloatMx fMxfmafN (_FloatN x, _FloatN y, _FloatN z)
_FloatMx fMxfmafNx (_FloatNx x, _FloatNx y, _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数,来自 TS 18661-1:2014 和 TS 18661-3:2015,返回 (x · y) + z,舍入一次到函数的返回类型,没有任何中间舍入到参数的类型,也没有任何中间 乘法结果的四舍五入。
2.9. 复数
Complex Numbers
ISO C99 在 C 中引入了对复数的支持。这是通过新的类型限定符 complex 完成的。当且仅当 complex.h 已包含时,它才是关键字。复数类型共有三种,分别对应三种实数类型:float complex、double complex、long double complex。
同样,在启用了 _FloatN 或 _FloatNx 支持的机器上,如果包含 complex.h,复杂类型 _FloatN complex 和 _FloatNx complex 也可用;见数学库。
要构造复数,您需要一种方法来表示数字的虚部。虚拟浮点常数没有标准表示法。相反,complex.h 定义了两个可用于创建复数的宏。
宏:const float complex _Complex_I
这个宏是复数“0+1i”的表示。将实数浮点值乘以 _Complex_I 会得到一个复数,其值是纯虚数。您可以使用它来构造复杂的常量:
3.0 + 4.0i = 3.0 + 4.0 * _Complex_I
请注意,_Complex_I * _Complex_I 的值为 -1,但该值的类型是复杂的。
_Complex_I 有点拗口。complex.h 还为同一常量定义了一个较短的名称。
宏:const float complex I
该宏的值与 _Complex_I 完全相同。大多数时候,它是可取的。但是,如果您想将标识符 I 用于其他用途,则会导致问题。你可以放心地写
#include <complex.h>
#undef I
如果你需要我为你自己的目的。(在这种情况下,我们建议您还为 _Complex_I 定义一些其他短名称,例如 J。)
2.10. 复数的投影、共轭和分解
Projections, Conjugates, and Decomposing of Complex Numbers
ISO C99 还定义了对复数执行基本运算的函数,例如分解和共轭。所有这些函数的原型都在 complex.h 中。所有功能都提供三种变体,一种用于三种复杂类型中的每一种。
函数:
double creal (complex double z)
float crealf (complex float z)
long double creall (complex long double z)
_FloatN crealfN (complex _FloatN z)
_FloatNx crealfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数 z 的实部。
函数:
double cimag (complex double z)
float cimagf (complex float z)
long double cimagl (complex long double z)
_FloatN cimagfN (complex _FloatN z)
_FloatNx cimagfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数 z 的虚部。
函数:
complex double conj (complex double z)
complex float conjf (complex float z)
complex long double conjl (complex long double z)
complex _FloatN conjfN (complex _FloatN z)
complex _FloatNx conjfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数 z 的共轭值。复数的共轭具有相同的实部和否定的虚部。换句话说,‘conj(a + bi) = a + -bi’。
函数:
double carg (complex double z)
float cargf (complex float z)
long double cargl (complex long double z)
_FloatN cargfN (complex _FloatN z)
_FloatNx cargfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数 z 的参数。复数的自变量是复平面中正实轴和通过零的线之间的角度和数字。该角度以通常的方式测量,范围从 -π 到 π。
carg 沿负实轴有一个分支。
函数:
complex double cproj (complex double z)
complex float cprojf (complex float z)
complex long double cprojl (complex long double z)
complex _FloatN cprojfN (complex _FloatN z)
complex _FloatNx cprojfNx (complex _FloatNx z)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数返回复数值 z 在黎曼球上的投影。具有无限虚部的值被投影到实轴上的正无穷大,即使实部是 NaN。如果实部是无限的,则结果等价于
INFINITY + I * copysign (0.0, cimag (z))
2.11. 数字解析
Parsing of Numbers
本节介绍从字符串中“读取”整数和浮点数的函数。在某些情况下使用 sscanf 或相关函数之一可能更方便;请参阅格式化输入。但通常您可以通过手动查找字符串中的标记,然后将数字一一转换来使程序更加健壮。
2.11.1. 整数解析
Parsing of Integers
“str”函数在 stdlib.h 中声明,以“wcs”开头的函数在 wchar.h 中声明。有人可能想知道在本节的函数原型中使用了限制。它看似无用,但 ISO C 标准使用它(对于那里定义的函数),所以我们也必须这样做。
函数:long int strtol (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtol(“string-to-long”)函数将字符串的初始部分转换为有符号整数,该整数作为 long int 类型的值返回。
此函数尝试按如下方式分解字符串:
-
一个(可能是空的)空白字符序列。哪些字符是空白字符由 isspace 函数确定(请参阅字符分类)。这些被丢弃。
-
可选的加号或减号(“+”或“-”)。
-
基数指定的非空数字序列。
如果基数为零,则假定为十进制基数,除非数字系列以“0”(指定八进制基数)或“0x”或“0X”(指定十六进制基数)开头;换句话说,与 C 中用于整数常量的语法相同。
否则 base 必须有一个介于 2 和 36 之间的值。如果 base 是 16,则可以选择在数字前面加上“0x”或“0X”。如果 base 没有合法值,则返回值为 0l,并且全局变量 errno 设置为 EINVAL。
-
字符串中的任何剩余字符。如果tailptr 不是空指针,strtol 将指向该尾的指针存储在*tailptr 中。
如果字符串为空、仅包含空格或不包含具有指定基数中整数的预期语法的初始子字符串,则不执行转换。在这种情况下,strtol 返回值为零,存储在 *tailptr 中的值是 string 的值。
在标准“C”语言环境以外的语言环境中,此函数可以识别附加的依赖于实现的语法。
如果字符串具有整数的有效语法,但由于溢出而无法表示该值,则 strtol 根据值的符号返回 LONG_MAX 或 LONG_MIN(请参阅整数类型的范围)。它还将 errno 设置为 ERANGE 以指示存在溢出。
您不应通过检查 strtol 的返回值来检查错误,因为该字符串可能是 0l、LONG_MAX 或 LONG_MIN 的有效表示。相反,请检查 tailptr 是否指向您期望的数字之后的内容(例如,如果字符串应该在数字之后结束,则为 ‘\0’)。您还需要在调用之前清除 errno 并在之后检查它,以防溢出。
本节末尾有一个示例。
函数:long int wcstol (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstol 函数在几乎所有方面都等效于 strtol 函数,但处理的是宽字符串。
wcstol 函数是在 ISO C90 的修正案 1 中引入的。
函数:unsigned long int strtoul (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoul(“string-to-unsigned-long”)函数与 strtol 类似,只是它转换为 unsigned long int 值。语法与上面描述的 strtol 相同。溢出时返回的值是 ULONG_MAX(请参阅整数类型的范围)。
如果 string 描述了一个负数,strtoul 的作用与 strtol 相同,但将结果转换为无符号整数。这意味着例如“-1”上的 strtoul 返回 ULONG_MAX 并且比 LONG_MIN 更负的输入返回 (ULONG_MAX + 1) / 2。
如果 base 超出范围,strtoul 将 errno 设置为 EINVAL,或者在溢出时设置 ERANGE。
函数:unsigned long int wcstoul (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoul 函数在几乎所有方面都等效于 strtoul 函数,但处理的是宽字符串。
wcstoul 函数是在 ISO C90 的修正案 1 中引入的。
函数:long long int strtoll (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoll 函数与 strtol 类似,只是它返回一个 long long int 值,并接受具有相应更大范围的数字。
如果字符串具有整数的有效语法,但由于溢出而无法表示该值,则 strtoll 根据值的符号返回 LLONG_MAX 或 LLONG_MIN(请参阅整数类型的范围)。它还将 errno 设置为 ERANGE 以指示存在溢出。
strtoll 函数是在 ISO C99 中引入的。
函数:long long int wcstoll (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoll 函数在几乎所有方面都等效于 strtoll 函数,但处理的是宽字符串。
wcstoll 函数是在 ISO C90 的修正案 1 中引入的。
函数:long long int strtoq (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoq (“string-to-quad-word”) 是 strtoll 的 BSD 名称。
函数:long long int wcstoq (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoq 函数在几乎所有方面都等效于 strtoq 函数,但处理的是宽字符串。
wcstoq 函数是一个 GNU 扩展。
函数:unsigned long long int strtoull (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoull 函数与 strtoll 的关联方式与 strtoul 与 strtol 的关联方式相同。
strtoull 函数是在 ISO C99 中引入的。
函数:unsigned long long int wcstoull (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoull 函数在几乎所有方面都等效于 strtoull 函数,但处理的是宽字符串。
wcstoull 函数是在 ISO C90 的修正案 1 中引入的。
函数:unsigned long long int strtouq (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtouq 是 strtoull 的 BSD 名称。
函数:unsigned long long int wcstouq (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstouq 函数在几乎所有方面都等效于 strtouq 函数,但处理的是宽字符串。
wcstouq 函数是一个 GNU 扩展。
函数:intmax_t strtoimax (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoimax 函数与 strtol 类似,只是它返回一个 intmax_t 值,并接受相应范围的数字。
如果字符串具有整数的有效语法,但由于溢出而无法表示该值,则 strtoimax 根据值的符号返回 INTMAX_MAX 或 INTMAX_MIN(请参阅整数)。它还将 errno 设置为 ERANGE 以指示存在溢出。
有关 intmax_t 类型的描述,请参见整数。strtoimax 函数是在 ISO C99 中引入的。
函数:intmax_t wcstoimax (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoimax 函数在几乎所有方面都等效于 strtoimax 函数,但处理的是宽字符串。
wcstoimax 函数是在 ISO C99 中引入的。
函数:uintmax_t strtoumax (const char *restrict string, char **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtoumax 函数与 strtoimax 的关联方式与 strtoul 与 strtol 的关联方式相同。
有关 intmax_t 类型的描述,请参见整数。strtoumax 函数是在 ISO C99 中引入的。
函数:uintmax_t wcstoumax (const wchar_t *restrict string, wchar_t **restrict tailptr, int base)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstoumax 函数在几乎所有方面都等效于 strtoumax 函数,但处理的是宽字符串。
wcstoumax 函数是在 ISO C99 中引入的。
函数:long int atol (const char *string)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数类似于具有 10 基参数的 strtol 函数,不同之处在于它不需要检测溢出错误。提供 atol 函数主要是为了与现有代码兼容;使用 strtol 更健壮。
函数:int atoi (const char *string)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数与 atol 类似,不同之处在于它返回一个 int。atoi 函数也被认为是过时的;改用 strtol 。
函数:long long int atoll (const char *string)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数类似于 atol,不同之处在于它返回一个 long long int。
atoll 函数是在 ISO C99 中引入的。它也已过时(尽管刚刚添加);使用 strtoll 代替。
到目前为止,本节中提到的所有函数都不能处理语言环境数据中描述的字符的替代表示。一些语言环境指定了千位分隔符以及它们必须使用的方式,这有助于使大数字更具可读性。要读取这样的数字,必须使用带有“”标志的 scanf 函数。
这是一个将字符串解析为整数序列并返回它们之和的函数:
int
sum_ints_from_string (char *string)
{
int sum = 0;
while (1) {
char *tail;
int next;
/* Skip whitespace by hand, to detect the end. */
while (isspace (*string)) string++;
if (*string == 0)
break;
/* There is more nonwhitespace, */
/* so it ought to be another number. */
errno = 0;
/* Parse it. */
next = strtol (string, &tail, 0);
/* Add it in, if not overflow. */
if (errno)
printf ("Overflow\n");
else
sum += next;
/* Advance past it. */
string = tail;
}
return sum;
}
2.11.2. 浮点数的解析
Parsing of Floats
“str”函数在 stdlib.h 中声明,以“wcs”开头的函数在 wchar.h 中声明。有人可能想知道在本节的函数原型中使用了限制。它看似无用,但 ISO C 标准使用它(对于那里定义的函数),所以我们也必须这样做。
函数:double strtod (const char *restrict string, char **restrict tailptr)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
strtod(“string-to-double”)函数将 string 的初始部分转换为浮点数,该浮点数作为 double 类型的值返回。
此函数尝试按如下方式分解字符串:
-
一个(可能是空的)空白字符序列。哪些字符是空白字符由 isspace 函数确定(请参阅字符分类)。这些被丢弃。
-
可选的加号或减号(“+”或“-”)。
十进制或十六进制格式的浮点数。十进制格式为:- 可选包含小数点字符的非空数字序列 — 通常为“.”,但它取决于语言环境(请参阅通用数字格式参数)。
- 可选的指数部分,由字符“e”或“E”、可选符号和数字序列组成。
十六进制格式如下:
- 一个 0x 或 0X 后跟一个非空的十六进制数字序列,可选地包含一个小数点字符——通常是“.”,但它取决于语言环境(请参阅通用数字格式参数)。
- 可选的二进制指数部分,由字符“p”或“P”、可选符号和数字序列组成。
-
字符串中的任何剩余字符。如果tailptr 不是空指针,则指向该字符串尾部的指针存储在*tailptr 中。
如果字符串为空、仅包含空格或不包含具有浮点数预期语法的初始子字符串,则不执行转换。在这种情况下,strtod 返回值为零,*tailptr 中返回的值是 string 的值。
在标准“C”或“POSIX”语言环境以外的语言环境中,此函数可以识别附加的与语言环境相关的语法。
如果字符串具有浮点数的有效语法但值超出双精度范围,则 strtod 将发出溢出或下溢信号,如数学函数错误报告中所述。
strtod 识别四个特殊的输入字符串。字符串“inf”和“infinity”被转换为∞,或者如果浮点格式不支持无穷大,则转换为最大的可表示值。您可以在前面加上“+”或“-”来指定符号。扫描这些字符串时忽略大小写。
字符串“nan”和“nan(chars…)”被转换为 NaN。同样,忽略大小写。如果提供了 chars…,它们会以某种未指定的方式用于选择 NaN 的特定表示(可能有多个)。
由于零是一个有效的结果以及错误返回的值,因此您应该通过检查 errno 和 tailptr 以与 strtol 相同的方式检查错误。
函数:
float strtof (const char *string, char **tailptr)
long double strtold (const char *string, char **tailptr)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数类似于 strtod,但分别返回 float 和 long double 值。它们以与 strtod 相同的方式报告错误。strtof 可以比 strtod 快得多,但精度较低;相反,strtold 可能慢得多,但精度更高(在 long double 是单独类型的系统上)。
这些函数是 GNU 扩展,是 ISO C99 的新功能。
函数:
_FloatN strtofN (const char *string, char **tailptr)
_FloatNx strtofNx (const char *string, char **tailptr)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这些函数类似于 strtod,除了返回类型。
它们是在 ISO/IEC TS 18661-3 中引入的,可在支持相关类型的机器上使用;见数学库。
函数:
double wcstod (const wchar_t *restrict string, wchar_t **restrict tailptr)
float wcstof (const wchar_t *string, wchar_t **tailptr)
long double wcstold (const wchar_t *string, wchar_t **tailptr)
_FloatN wcstofN (const wchar_t *string, wchar_t **tailptr)
_FloatNx wcstofNx (const wchar_t *string, wchar_t **tailptr)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
wcstod、wcstof、wcstol、wcstofN 和 wcstofNx 函数在几乎所有方面都等效于 strtod、strtof、strtold、strtofN 和 strtofNx 函数,但它们处理宽字符串。
wcstod 函数是在 ISO C90 的修正案 1 中引入的。wcstof 和 wcstold 函数是在 ISO C99 中引入的。
wcstofN 和 wcstofNx 函数不在任何标准中,但被添加以提供宽字符串到浮点转换函数的非弃用接口的完整性。它们仅在支持相关类型的机器上可用;见数学库。
函数:double atof (const char *string)
Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
此函数类似于 strtod 函数,不同之处在于它不需要检测上溢和下溢错误。提供 atof 函数主要是为了与现有代码兼容;使用 strtod 更健壮。
GNU C 库还提供了这些函数的“_l”版本,它们带有一个额外的参数,即在转换中使用的语言环境。
另请参阅整数解析。
2.12. 浮点数的打印
Printing of Floats
“strfrom”函数在 stdlib.h 中声明。
函数:
int strfromd (char *restrict string, size_t size, const char *restrict format, double value)
int strfromf (char *restrict string, size_t size, const char *restrict format, float value)
int strfroml (char *restrict string, size_t size, const char *restrict format, long double value)
Preliminary: | MT-Safe locale | AS-Unsafe heap | AC-Unsafe mem | See POSIX Safety Concepts.
函数 strfromd(“string-from-double”)、strfromf(“string-from-float”)和 strfroml(“string-from-long-double”)将浮点数值转换为字符串,并将它们存储到字符串指向的区域中。转换最多写入 size 个字符并遵守 format 指定的格式。
格式字符串必须以字符“%”开头。后面是一个可选的精度,它以句点“.”开头,后面可以跟一个十进制整数,表示精度。如果句点后未指定十进制整数,则精度为零。不允许使用字符“*”。最后,格式字符串以下列转换说明符之一结尾:“a”、“A”、“e”、“E”、“f”、“F”、“g”或“G”(参见输出表转换)。无效的格式字符串会导致未定义的行为。
如果大小足够大,这些函数会返回将写入字符串的字符数,不包括终止的空字符。因此,当且仅当返回值小于 size 时,以 null 结尾的输出已被完全写入。
这些功能由 ISO/IEC TS 18661-1 引入。
函数:
int strfromfN (char *restrict string, size_t size, const char *restrict format, _FloatN value)
int strfromfNx (char *restrict string, size_t size, const char *restrict format, _FloatNx value)
Preliminary: | MT-Safe locale | AS-Unsafe heap | AC-Unsafe mem | See POSIX Safety Concepts.
这些函数类似于 strfromd,除了值的类型。
它们是在 ISO/IEC TS 18661-3 中引入的,可在支持相关类型的机器上使用;见数学库。
2.13. 老式 System V 数字到字符串函数
Old-fashioned System V number-to-string functions
旧的 System V C 库提供了三个函数来将数字转换为字符串,具有不寻常且难以使用的语义。GNU C 库也提供了这些函数和一些自然扩展。
这些函数仅在 GNU C 库和源自 AT&T Unix 的系统中可用。因此,除非这些函数完全满足您的需要,否则最好使用标准的 sprintf。
所有这些函数都在 stdlib.h 中定义。
函数:char * ecvt (double value, int ndigit, int *decpt, int *neg)
Preliminary: | MT-Unsafe race:ecvt | AS-Unsafe | AC-Safe | See POSIX Safety Concepts.
函数 ecvt 将浮点数值转换为最多 ndigit 十进制数字的字符串。返回的字符串不包含小数点或符号。字符串的第一个数字非零(除非值实际上为零),最后一个数字四舍五入到最接近的值。*decpt 设置为字符串中小数点后第一位的索引。如果值为负,*neg 设置为非零值,否则为零。
如果 ndigit 十进制数字超过 double 的精度,则将其缩减为系统特定的值。
每次调用 ecvt 时都会静态分配和覆盖返回的字符串。
如果 value 为零,则由实现定义 *decpt 是 0 还是 1。
例如:ecvt (12.3, 5, &d, &n) 返回“12300”并将 d 设置为 2 并将 n 设置为 0。
函数:char * fcvt (double value, int ndigit, int *decpt, int *neg)
Preliminary: | MT-Unsafe race:fcvt | AS-Unsafe heap | AC-Unsafe mem | See POSIX Safety Concepts.
fcvt 函数与 ecvt 类似,但 ndigit 指定小数点后的位数。如果 ndigit 小于零,则将值四舍五入到小数点左侧的第 ndigit+1 位。例如,如果 ndigit 为 -1,则 value 将四舍五入到最接近的 10。如果 ndigit 为负数并且大于 value 小数点左侧的位数,则 value 将四舍五入为一位有效数字。
如果 ndigit 十进制数字超过 double 的精度,则将其缩减为系统特定的值。
每次调用 fcvt 时都会静态分配和覆盖返回的字符串。
函数:char * gcvt (double value, int ndigit, char *buf)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
gcvt 在功能上等同于‘sprintf(buf, “%*g”, ndigit, value)’。它只是为了兼容性而提供的。它返回缓冲区。
如果 ndigit 十进制数字超过 double 的精度,则将其缩减为系统特定的值。
作为扩展,GNU C 库提供了这三个采用长双参数的函数的版本。
函数:char * qecvt (long double value, int ndigit, int *decpt, int *neg)
Preliminary: | MT-Unsafe race:qecvt | AS-Unsafe | AC-Safe | See POSIX Safety Concepts.
这个函数等价于 ecvt,除了它的第一个参数需要一个 long double 并且 ndigit 受 long double 的精度限制。
函数:char * qfcvt (long double value, int ndigit, int *decpt, int *neg)
Preliminary: | MT-Unsafe race:qfcvt | AS-Unsafe heap | AC-Unsafe mem | See POSIX Safety Concepts.
这个函数等价于 fcvt,除了它的第一个参数需要一个 long double 并且 ndigit 受 long double 的精度限制。
函数:char * qgcvt (long double value, int ndigit, char *buf)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
这个函数等价于 gcvt,除了它的第一个参数需要一个 long double 并且 ndigit 受 long double 的精度限制。
ecvt 和 fcvt 函数,以及它们的 long double 等价函数,都返回一个位于静态缓冲区中的字符串,该字符串被下一次调用该函数覆盖。GNU C 库提供了另一组扩展函数,它们将转换后的字符串写入用户提供的缓冲区。这些具有常规的 _r 后缀。
gcvt_r 不是必需的,因为 gcvt 已经使用了用户提供的缓冲区。
函数:int ecvt_r (double value, int ndigit, int *decpt, int *neg, char *buf, size_t len)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
ecvt_r 函数与 ecvt 相同,只是它将其结果放入由 buf 指向的用户指定的缓冲区,长度为 len。发生错误时返回值为 -1,否则返回值为 0。
这个函数是一个 GNU 扩展。
函数:int fcvt_r (double value, int ndigit, int *decpt, int *neg, char *buf, size_t len)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
fcvt_r 函数与 fcvt 相同,只是它将其结果放入由 buf 指向的用户指定的缓冲区,长度为 len。发生错误时返回值为 -1,否则返回值为 0。
这个函数是一个 GNU 扩展。
函数:int qecvt_r (long double value, int ndigit, int *decpt, int *neg, char *buf, size_t len)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
qecvt_r 函数与 qecvt 相同,只是它将其结果放入由 buf 指向的用户指定的缓冲区,长度为 len。发生错误时返回值为 -1,否则返回值为 0。
这个函数是一个 GNU 扩展。
函数:int qfcvt_r (long double value, int ndigit, int *decpt, int *neg, char *buf, size_t len)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
qfcvt_r 函数与 qfcvt 相同,只是它将其结果放入由 buf 指向的用户指定的缓冲区,长度为 len。发生错误时返回值为 -1,否则返回值为 0。
这个函数是一个 GNU 扩展。