ilogb, ilogbf, ilogbl
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定义于头文件
<math.h>
|
||
|
int
ilogbf
(
float
arg
)
;
|
(1) | (C99 起) |
|
int
ilogb
(
double
arg
)
;
|
(2) | (C99 起) |
|
int
ilogbl
(
long
double
arg
)
;
|
(3) | (C99 起) |
|
定义于头文件
<tgmath.h>
|
||
|
#define ilogb( arg )
|
(4) | (C99 起) |
|
定义于头文件
<math.h>
|
||
|
#define FP_ILOGB0 /* 由实现定义 */
|
(5) | (C99 起) |
|
#define FP_ILOGBNAN /* 由实现定义 */
|
(6) | (C99 起) |
ilogbl
。否则,若
arg
具有整数类型或
double
类型,则调用
ilogb
。否则,调用
ilogbf
。
形式上,对于非零的
arg
,无偏指数是指
log
r
|arg|
的整数部分作为有符号整数值,其中
r
是
FLT_RADIX
。
目录 |
参数
| arg | - | 浮点数值 |
返回值
如果未发生错误,则返回 arg 的无偏指数作为有符号整型值。
如果 arg 为零,则返回 FP_ILOGB0 。
如果 arg 为无穷大,则返回 INT_MAX 。
如果 arg 是 NaN,则返回 FP_ILOGBNAN 。
如果正确结果大于 INT_MAX 或小于 INT_MIN ,则返回值是未指定的,并且可能出现定义域错误或值域错误。
错误处理
错误报告方式遵循
math_errhandling
中的规范。
当 arg 为零、无穷大或 NaN 时,可能出现定义域错误或值域错误。
如果正确结果大于 INT_MAX 或小于 INT_MIN ,则可能出现定义域错误或范围错误
如果实现支持 IEEE 浮点算术 (IEC 60559),
- 如果正确结果大于 INT_MAX 或小于 INT_MIN ,将引发 FE_INVALID 。
- 如果 arg 为 ±0、±∞ 或 NaN,将引发 FE_INVALID 。
- 在所有其他情况下,结果是精确的(永远不会引发 FE_INEXACT )且忽略 当前舍入模式 。
注释
如果 arg 不为零、无穷大或 NaN,则返回值完全等同于 ( int ) logb ( arg ) 。
POSIX要求 ,如果 arg 为零、无穷大、NaN,或者正确结果超出 int 的范围,则会发生定义域错误。
POSIX 还要求,在符合 XSI 标准的系统中,当正确结果大于 INT_MAX 时返回的值为 INT_MAX ,当正确结果小于 INT_MIN 时返回的值为 INT_MIN 。
在所有已知实现中,正确结果可以表示为 int 。要发生溢出,必须满足 INT_MAX 小于 LDBL_MAX_EXP * log2 ( FLT_RADIX ) 或 INT_MIN 大于 LDBL_MIN_EXP - LDBL_MANT_DIG ) * log2 ( FLT_RADIX ) 。
ilogb
返回的指数值总是比
frexp
返回的指数小 1,这是因为不同的归一化要求:对于
ilogb
返回的指数
e
,
|arg*r
-e
|
在 1 和
r
之间(通常在
1
和
2
之间),但对于
frexp
返回的指数
e
,
|arg*2
-e
|
在
0.5
和
1
之间。
示例
#include <fenv.h> #include <float.h> #include <math.h> #include <stdio.h> // #pragma STDC FENV_ACCESS ON int main(void) { double f = 123.45; printf("给定数字 %.2f 或十六进制格式 %a,\n", f, f); double f3; double f2 = modf(f, &f3); printf("modf() 生成 %.0f + %.2f\n", f3, f2); int i; f2 = frexp(f, &i); printf("frexp() 生成 %f * 2^%d\n", f2, i); i = ilogb(f); printf("logb()/ilogb() 生成 %f * %d^%d\n", f/scalbn(1.0, i), FLT_RADIX, i); // 错误处理 feclearexcept(FE_ALL_EXCEPT); printf("ilogb(0) = %d\n", ilogb(0)); if (fetestexcept(FE_INVALID)) puts(" FE_INVALID 已触发"); }
可能的输出:
给定数字 123.45 或十六进制格式 0x1.edccccccccccdp+6,
modf() 生成 123 + 0.45
frexp() 生成 0.964453 * 2^7
logb()/ilogb() 生成 1.92891 * 2^6
ilogb(0) = -2147483648
FE_INVALID 已触发
参考文献
- C23 标准 (ISO/IEC 9899:2024):
-
- 7.12/8 数学函数 <math.h> (页: 待定)
-
- 7.12.6.5 ilogb 函数族 (页: 待定)
-
- 7.25 泛型数学 <tgmath.h> (页: 待定)
-
- F.10.3.5 ilogb 函数族 (页: 待定)
- C17 标准 (ISO/IEC 9899:2018):
-
- 7.12/8 数学函数 <math.h> (页: 待定)
-
- 7.12.6.5 ilogb 函数族 (页: 待定)
-
- 7.25 泛型数学 <tgmath.h> (页: 待定)
-
- F.10.3.5 ilogb 函数族 (页: 待定)
- C11 标准 (ISO/IEC 9899:2011):
-
- 7.12/8 数学函数 <math.h> (页码: 232)
-
- 7.12.6.5 ilogb 函数族 (页码: 244)
-
- 7.25 泛型数学 <tgmath.h> (页码: 373-375)
-
- F.10.3.5 ilogb 函数族 (页码: 521)
- C99标准(ISO/IEC 9899:1999):
-
- 7.12/8 数学函数 <math.h>(页码:213)
-
- 7.12.6.5 ilogb函数(页码:224-225)
-
- 7.22 泛型数学 <tgmath.h>(页码:335-337)
-
- F.9.3.5 ilogb函数(页码:458)
参考
|
(C99)
(C99)
|
将数字分解为有效数和
2
的幂次
(函数) |
|
(C99)
(C99)
(C99)
|
提取给定数字的指数
(函数) |
|
(C99)
(C99)
(C99)
(C99)
(C99)
(C99)
|
高效计算数字乘以
FLT_RADIX
的指定幂次
(函数) |
|
C++ 文档
关于
ilogb
|
|