gpt4 book ai didi

c - 如何将信号 NaN 转换为安静 NaN?

转载 作者:行者123 更新时间:2023-12-05 01:48:41 25 4
gpt4 key购买 nike

我想在 C 中将信号 NaN 转换为静默 NaN。有人可以推荐一种方法吗?

谢谢。

最佳答案

我想我会扩展我的评论并提供解决方案。

这里棘手的部分是能够在不触发异常的情况下读取/比较 sNaN。毕竟它被称为“信号”是有原因的。 Wikipedia says that even comparison operations on sNaN will trigger an exception.

因此直接使用 number != numberisnan(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 和整数单元之间移动数据,因此这种方法不是特别有效。

这是它的工作原理:

  1. union 显然用于将float 的位转换为int
  2. 所有 NaN 的位都在 0x7f80000 集合中。 if 语句测试将检查是否所有这些位都已设置。
  3. 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():

看到这个问题:Where is the source code for isnan?

关于c - 如何将信号 NaN 转换为安静 NaN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8180752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com