如何在MSVC ++ 6中声明IEEE数学函数,如'ilogbf'?

时间:2009-11-13 03:09:38

标签: c visual-c++ c99 vc6

有人可以帮助并告诉我如何在MSVC ++ 6中包含IEEE数学函数吗?我试过了两个,但我仍然遇到这些错误:

  

错误C2065:'ilogbf':未声明的标识符

     

错误C2065:'scalbnf':未声明的标识符

3 个答案:

答案 0 :(得分:2)

编辑3:希望这将是我的最终编辑。我已经意识到我根本没有妥善解决这个问题。我将把我的答案作为一个警示故事留下来,因为它可能具有一定的教育价值。但我理解为什么我没有赞成票,事实上我会赞成安迪罗斯的回答,因为我认为他的相关性更高(尽管至少在写作时不完整)。在我看来,我的错误是把我为ilogbf()找到的Man定义略显表面。它是一个函数,它接受float的日志的整数部分,这有多难实现?事实证明,该功能实际上是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;
}

编辑:这不太对劲。显然,这个函数应该使用log到base 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;
}

答案 1 :(得分:2)

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

全新的754标准IEEE754-2008要求具备这些功能(第5.3.3条,“logBFormat操作”),但该标准的版本将不会被广泛采用多年;即使它确实被广泛采用,微软还没有看到它们在C99中使用这些功能已经十年了,那么为什么他们只是因为它们符合IEEE754标准而无法提供这些功能呢?

编辑请注意,scalb和logb是在IEEE754-1985 附录“推荐功能和谓词”中定义的,但附录明确表示“不属于”说标准。

答案 2 :(得分:1)

如果你知道你在IEEE系统上(现在,你这样做),则不需要这些函数:只需通过将double与uint64_t结合起来直接检查这些位。假设您首先是为了提高效率而使用这些功能(否则您将使用更自然的操作,如log()exp()),因此需要花费一些精力来匹配您的代码浮点表示可能是值得的。