0

Could someone please help and tell me how to include IEEE mathematical functions in MSVC++6? I tried both and , but I still get these errors:

error C2065: 'ilogbf' : undeclared identifier

error C2065: 'scalbnf' : undeclared identifier

4

3 回答 3

2

编辑 3:希望这将是我的最终编辑。我开始意识到我根本没有正确解决这个问题。我将把我的答案作为一个警示故事留在原地,因为它可能具有一定的教育价值。但我理解为什么我的赞成票为零,事实上我会赞成安迪·罗斯的回答,因为我认为他的答案更相关(尽管至少在撰写本文时不完整)。在我看来,我的错误是将我为 ilogbf() 找到的 Man 定义略为肤浅。这是一个采用浮点数对数的整数部分的函数,实现起来有多难?事实证明,该函数的真正含义是 IEEE 浮点表示,特别是该表示的指数(与尾数相反)部分。在尝试回答问题之前,我绝对应该意识到这一点!对我来说有趣的一点是函数如何找到浮点数的指数部分,因为我认为 C 的基本规则是浮点数作为函数调用的一部分被提升为双精度数。但这当然是一个完全独立的讨论。

--- 编辑 3 结束,警示故事开始 ---

一点谷歌搜索表明这些是在某些风格的 Unix 中定义的,但可能不在任何 Posix 或 ANSI 标准中,因此没有随 MSVC 库提供。如果函数不在库中,它们将不会在 math.h 中声明。显然,如果编译器看不到这些外部符号的声明,它会不高兴,并且您会得到与您列出的错误类似的错误。

显而易见的解决方法是使用提供的数学函数创建您自己的这些函数版本。例如

#include <math.h>

int ilogbf( float f )
{
    double d1 = (double)f;
    double d2 = log(d1);
    int ret = (int)d2;
    return ret;
}

编辑:这不太对。显然,这个函数应该使用以 2 为底的对数,而不是自然对数,这样返回的值实际上是一个二进制指数。它还应该采用其参数的绝对值,以便它也适用于负数。如果你在评论中问我,我会改进版本,否则我很想把它作为练习留给读者:-)

我的回答的本质,即 ANSI C 不需要这个函数并且 MSVC 不包含它,显然是正确的。

编辑2:好的,我已经削弱并提供了改进的版本而没有被问到。这里是;

#include <math.h>

int ilogbf( float f )
{
    double d1 = (double)f;
    if( d1 < 0 )
        d1 = -d1;
    double d2 = log(d1) / log(2);  // log2(x) = ln(x)/ln(2)
    int ret = (int)d2;
    return ret;
}
于 2009-11-13T04:41:48.840 回答
2

这些是 C99 函数,而不是 IEEE754-1985。微软似乎已经决定他们的市场不关心 C99 支持,所以他们没有费心提供它们。这是一种耻辱,但除非你们中的更多人(开发人员)抱怨,否则没有理由期望情况会改变。

全新的 754 标准 IEEE754-2008 需要这些功能(第 5.3.3 节,“logBFormat 操作”),但该版本的标准在未来几年内不会被广泛采用;即使它确实得到了广泛采用,微软在 C99 中的十年里也认为不适合提供这些功能,那么他们为什么仅仅因为它们在 IEEE754 标准中而费心提供它们呢?

编辑:请注意,scalb 和 logb 在 IEEE754-1985附录“推荐函数和谓词”中定义,但所述附录明确“不是”所述标准的一部分。

于 2009-11-14T00:31:14.990 回答
1

如果你知道你在一个 IEEE 系统上(现在你确实这样做了),那么就不需要这些函数:只需通过将双精度与 uint64_t 联合来直接检查位。大概您首先是为了提高效率而使用这些函数(否则您将使用更自然的操作,例如log()or exp()),因此花一点精力将您的代码与浮点表示相匹配可能是值得的。

于 2009-11-13T05:30:39.077 回答