【问题标题】:identifying and assigning +NaN and -NaN in C在 C 中识别和分配 +NaN 和 -NaN
【发布时间】:2019-09-04 14:28:56
【问题描述】:

对于一个问题,我必须在float 中输入 +NaN 或 -NaN 并转换为另一种名为 tinyfp(1 个符号位、3 个指数位、4 个小数位)的人工浮点形式,

或在 tinyfp 中获取输入(每个都显示 +NaN 或 -NaN)并回答为 +NaN 或 -NaN

问题具体问

float 中的 +NaN 和 -NaN 应分别转换为 tinyfp 中对应的 +NaN 和 -NaN。

tinyfp 中的+NaN 和 -NaN 应分别转换为对应的 float 中的 +NaN 和 -NaN。


第一个问题是,由于我无法将 NaN 与任何东西(甚至它本身)进行比较,虽然我可以识别输入值是否为 NaN,但我无法区分 +NaN 和 -NaN。

与第二个问题类似,当我想回答为 +NaN 或 -NaN 时,0.0/0.0 和 -0.0/0.0 都表示为 -NaN,所以我无法回答为 +NaN。

我尝试了if( input == 0.0/0.0)(input == -0.0/0.0),但它们不起作用。 我可以尝试if(input != input),但是我无法区分+NaN和-NaN。

对于第二个问题,我尝试了 return 0.0/0.0return -0.0/0.0,但最终都回答为 -NaN。 (虽然我可以通过 nan 和 -nan 获得输入)


所以问题是,我如何检查输入是 +NaN 还是 -NaN,当我想回答为 NaN 时,如何以不同的方式分配 +NaN 和 -NaN?

我不允许使用除 stdio.h + 以外的任何标头,我也不能使用 double 格式 - 只允许使用 float

【问题讨论】:

标签: c floating-point nan


【解决方案1】:

如果您不允许使用math.h,那么您只能靠自己,并且必须从其二进制表示中提取有关浮点值的信息。为此,您需要了解浮点数是如何存储在IEEE-754 format 中的(假设floatIEEE-754 single precision)。如果您不知道浮点类型是如何存储的,那么如何在 tinyfp 中构造值?

所以基本上一个浮点数表示为s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm,三个部分分别是符号-指数-尾数。您只需要使用各种方式获取底层位。然后检查if (eeeeeeee == 0xFF),因为最大的指数是为 IEEE-754 中的 inf 和 nan 保留的。现在阅读尾数以了解它是 inf 还是 nan。获得±inf±nan 的符号很简单,因为您已经有了符号位。这些都在标准中指定了,请检查一下

【讨论】:

    【解决方案2】:

    您对可以使用哪些函数/标头的限制给人一种强烈的印象,即您应该直接分析和操纵floats 的表示。这也将假定特定 float 表示的假设,但大端 IEEE-754 binary32 格式是一个不错的选择。我想你已经在研究这个了。

    您可以通过unsigned char 指针访问浮点值的表示:

    _Bool my_isnan(float f) {
        unsigned char *bytes = (unsigned char *) &f;
        // analyze bytes[0], bytes[1], etc. ...
    }
    

    您可以通过类似的方式操纵float 表示。

    我把分析/操作的细节留给你,因为这似乎是练习的重点,我不会为你做功课。

    【讨论】:

      【解决方案3】:

      您可以使用isnanisinf 函数。

      要创建 inf 和 -inf 数字,您可以使用 1.0/0.0(应该给出 inf)和 -1.0/0.0(应该给出 -inf)。

      例子:

      #include <stdio.h>
      #include <math.h>
      int main() {
        double x = 1.0/0.0;
        double y = -1.0/0.0;
        double z = sqrt(-1.0);
        printf("x = %f\n", x);
        printf("y = %f\n", y);
        printf("isinf(x) = %d\n", isinf(x));
        printf("isinf(y) = %d\n", isinf(y));
        printf("isnan(x) = %d\n", isnan(x));
        printf("isnan(z) = %d\n", isnan(z));
      }
      

      【讨论】:

      • 我不允许使用 math.h 标头。我对inf和-inf没有问题,nan和-nan是麻烦
      • @Kwon 但你为什么认为有“负面”南这样的东西?我认为 inf 可以是 + 或 - 但 nan 不能。见en.wikipedia.org/wiki/IEEE_754
      • @Elias NaN 具有符号位,可使用 copysign 设置,并使用 signbit 读取。
      猜你喜欢
      • 2016-03-19
      • 2013-07-23
      • 2022-01-25
      • 2019-07-11
      • 2021-11-29
      • 2021-01-09
      • 1970-01-01
      • 2015-05-14
      • 2021-04-25
      相关资源
      最近更新 更多