- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在 C 中将信号 NaN 转换为静默 NaN。有人可以推荐一种方法吗?
谢谢。
最佳答案
我想我会扩展我的评论并提供解决方案。
这里棘手的部分是能够在不触发异常的情况下读取/比较 sNaN
。毕竟它被称为“信号”是有原因的。 Wikipedia says that even comparison operations on sNaN
will trigger an exception.
因此直接使用 number != number
或 isnan(value)
可能不起作用,因为它们会调用比较并会触发硬件异常。 (虽然我不完全确定 isnan(value)
是如何实现的。)
编辑: 更正,看起来 isnan()
即使在信号 NaN
上也永远不会触发异常,因此剩下的这个答案毫无意义。
The predicate isNaN(x) determines if a value is a NaN and never signals an exception, even if x is a signaling NaN.
这意味着它可以像 Chrisoph 在评论中建议的那样完成:
if(isnan(value))
value = NAN;
这是我未使用 isnan(value)
的原始答案:
所以我能想到的唯一方法就是采用按位方式。
假设 float
是标准的 IEEE 单精度并且 int
是一个 32 位整数,那么这里有一种方法可以解决这个问题:(请注意,我还没有对此进行了测试。)
union{
int i;
float f;
} val;
val.f = // Read the value here.
// If NaN, force it to a quiet NaN.
if ((val.i & 0x7f800000) == 0x7f800000){
val.i |= 0x00400000;
}
请注意,此方法不完全符合 C 语言,并且会调用实现定义的行为。另请注意,由于需要在 FP 和整数单元之间移动数据,因此这种方法不是特别有效。
这是它的工作原理:
float
的位转换为int
。NaN
的位都在 0x7f80000
集合中。 if 语句测试将检查是否所有这些位都已设置。i |= 0x00400000;
强制 NaN
为安静的 NaN
。第 22 位确定 NaN
是静音还是静音。强制它为 1 将使它成为安静的 NaN
。编辑 2:如果您不能使用 union ,这里有一些其他方法(每种方法都有其自身的缺点):
方法一:
float f = // Read the value here.
int i = *(int*)&f;
if ((i & 0x7f800000) == 0x7f800000){
i |= 0x00400000;
}
f = *(float*)&i;
缺点:它违反了严格的别名,但可能仍然有效。
方法二:
char buf[sizeof(float)];
float f = // Read the value here.
*(float*)&buf = f;
int i = *(int*)&buf;
if ((i & 0x7f800000) == 0x7f800000){
i |= 0x00400000;
}
*(int*)&buf = i;
f = *(float*)&buf;
同样的想法适用于 memcpy()
。
缺点:如果对齐很重要,您需要确保 buf
对齐。
方法 3:实现您自己的 isnan()
:
关于c - 如何将信号 NaN 转换为安静 NaN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8180752/
我是一名优秀的程序员,十分优秀!