c - 这些函数有什么作用?
问题描述
我从其他人编写的代码中找到了以下两个函数,但我真的不明白这些函数的作用。
typedef union
{
t_float f; //float
unsigned int ui;
}t_bigorsmall32;
static inline int PD_BADFLOAT(t_float f) /* malformed float */
{
t_bigorsmall32 pun;
pun.f = f;
pun.ui &= 0x7f800000;
return((pun.ui == 0) | (pun.ui == 0x7f800000));
}
static inline int PD_BIGORSMALL(t_float f) /* exponent outside (-64,64) */
{
t_bigorsmall32 pun;
pun.f = f;
return((pun.ui & 0x20000000) == ((pun.ui >> 1) & 0x20000000));
}
如果有人能解释他们的工作,我将不胜感激。而且我还想知道是否有来自标准库或 C++ 的内置替代函数。
解决方案
很容易看出,代码通过联合类型双关将字节IEEE 754 binary32 float重新解释为 32 位无符号整数。然后它使用逐位运算来检查浮点数指数中的特定位。了解它的实际作用需要对 binary32 存储格式有复杂的了解。
PD_BADFLOAT
检查偏置指数是 0 还是最大值 255,因为0 和 255 具有特殊含义(指数为 0 的那些是次正规数和零;而 255 表示 NaN 和无穷大)。但是请注意,这些不是糟糕的浮点数- 但它们的行为也不像常规数字。
第二个检查无偏指数是否超出范围 [-63, 65] (描述似乎是错误的边界)意味着它的大小高于 2⁶⁵ (~ 3.7 * 10¹⁹) 或低于 2⁻⁶³, ( ~ 1.08 * 10⁻¹⁹)。
所有这些都是非常特定于实现且不可移植的——似乎这些都是在考虑速度的情况下进行编程的。
前者完全等同于标准宏的否定isnormal
。
对于后者,我认为可移植的方法是使用 C99+ 函数frexpf
从 中获取指数float
,然后与所需的限制进行比较,或者仅构造表示这些值的常量并将绝对值与这些限制进行比较。
因此像
static inline int PD_BADFLOAT(float f) {
return !isnormal(f);
}
static inline int PD_BIGORSMALL(float f) {
int exp;
if (isnormal(f)) {
frexpf(f, &exp);
return exp < -63 || exp > 65;
}
// return 1 for subnormal numbers and
// NaN, INF...
return 1;
}
推荐阅读
- r - Several find and replace from text file
- pdf-generation - Angular @Input ngIf 和 PDF 的生成
- javascript - 为什么我的猫鼬 findOne 查询返回多个结果
- swift - Swift 5 中从日期时间字符串到当前时间的天数时差
- flutter - Flutter 在滚动 ListView 上显示和隐藏容器
- java - 使用 Java 8 Stream forEach 方法迭代 char 数组
- python - Regex for prohibiting surrogates in python
- amazon-qldb - Amazon QLDB have any scaling/performance limits?
- spring-boot - What is the difference between eureka.instance.instance-id and eureka.instance.metadataMap.instanceId?
- javascript - 存根问题返回承诺的函数 - mocha