如何转换信号NaN的安静喃? [英] How to convert signalling NaN to quiet NaN?

查看:158
本文介绍了如何转换信号NaN的安静喃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要转换信号NaN的安静楠C.任何人可以提出一个方法是什么?

I want to convert signalling NaN to quiet NaN in C. Could anybody suggest a method?

感谢。

推荐答案

我想我会扩大我的意见,并提供解决方案。

I guess I'll expand on my comment and provide a solution.

在这里棘手的部分是能够读取/比较 SNAN 不触发异常。毕竟这就是所谓的信号的一个原因。 维基百科说,关于 SNAN 甚至比较操作会触发一个例外。

The tricky part here is being able to read/compare the sNaN without triggering an exception. After all it's called "signalling" for a reason. Wikipedia says that even comparison operations on sNaN will trigger an exception.

所以直接使用若干!=号 isnan(值)可能不工作,因为他们调用比较,将引发硬件异常。 (我不完全知道如何 isnan(值)不过是实现)。

So a direct use of number != number or isnan(value) probably don't work because they invoke comparisons and will trigger a hardware exception. (I'm not entirely sure how isnan(value) is implemented though.)

编辑:校正,它看起来像 isnan()绝不会触发一个例外,甚至在信号 NaN的这样就使得这个答案的其余部分没有意义的。

EDIT : Correction, it looks like isnan() will never trigger an exception even on a signalling NaN so that makes the rest of this answer pointless.

在predicate isNaN(x)的确定值是NaN,从不
  信号异常时,即使x是一个信令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的建议:

Meaning it can be done as just this as suggested by Chrisoph in the comments:

if(isnan(value))
    value = NAN;


这里是我原来的答复,不使用 isnan(值)


Here's my original answer that doesn't use isnan(value):

所以,我能想到这样做的唯一的办法就是去按位路线。

So the only way I can think of doing this is to go the bitwise route.

假设浮动是标准的IEEE单precision和 INT 是一个32位整数,然后这里是去了解一个方法:(请注意,我没有测试过这一点)

Assuming float is standard IEEE single-precision and int is a 32-bit integer, then here's one way to go about this: (Note that I haven't tested this.)

union{
    int i;
    float f;
} val;

val.f = //  Read the value here.

//  If NaN, force it to a quiet NaN.
if ((val.i & 0x7f80000) == 0x7f80000){
    val.i |= 0x00400000;
}

请注意,这种方法并不完全C-标准,将调用实现定义的行为。还注意到,这种方法是不是特别有效,因为需要对FP和整数单元之间移动数据。

Note that this approach is not completely C-compliant and will invoke implementation defined behavior. Also note that this approach is not particularly efficient due to the need to move data between the FP and integer units.

下面是如何工作的:


  1. 工会显然是用来浮动的位进入一个 INT

  2. 所有的NaN 将在 0x7f80000 位设定。 if语句测试将检查是否所有这些位的设置。

  3. I | = 0x00400000; 强制 NaN的来一个安静的 NaN的。 22位决定了 NaN的是沉默或安静。它强制为1将使它成为一个安静的 NaN的

  1. The union obviously is used to get the bits of the float into an int.
  2. All NaNs will have the bits in the 0x7f80000 set. The if-statement test will check if all of these bits are set.
  3. i |= 0x00400000; forces the NaN to a quiet NaN. Bit 22 determines whether the NaN is silent or quiet. Forcing it to 1 will make it a quiet NaN.

编辑2:如果您不能使用工会,这里的一些其他的办法(每个都有自己的缺点):


EDIT 2: If you can't use unions, here's are some other approaches (each of which have their own drawbacks):

方法1:

float f = //  Read the value here.

int i = *(int*)&f;
if ((i & 0x7f80000) == 0x7f80000){
    i |= 0x00400000;
}

f = *(float*)&i;

不足:它违反了严格的走样,但仍然可能会正常工作

Downside: It violates strict aliasing, but will probably still work.

方法2:

char buf[sizeof(float)];

float f = //  Read the value here.

*(float*)&buf = f;
int i = *(int*)&buf;

if ((i & 0x7f80000) == 0x7f80000){
    i |= 0x00400000;
}

*(int*)&buf = i;
f = *(float*)&buf;

同样的想法与工作的memcpy()

缺点:如果对齐问题,你需要确保 BUF 对齐

Downside: If alignment matters, you need to make sure buf is aligned.

方法3:实施自己的 isnan()

请参阅这个问题:哪里是源头code对于isnan?

这篇关于如何转换信号NaN的安静喃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆