如何在 MSVC++6 中声明 IEEE 数学函数,如“ilogbf”?
Posted
技术标签:
【中文标题】如何在 MSVC++6 中声明 IEEE 数学函数,如“ilogbf”?【英文标题】:How to declare IEEE mathematical functions like 'ilogbf' in MSVC++6? 【发布时间】:2009-11-13 03:09:38 【问题描述】:有人可以帮忙告诉我如何在 MSVC++6 中包含 IEEE 数学函数吗?和 都试过了,但我仍然得到这些错误:
错误 C2065:“ilogbf”:未声明的标识符
错误 C2065:“scalbnf”:未声明的标识符
【问题讨论】:
【参考方案1】:编辑 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;
【讨论】:
【参考方案2】:这些是 C99 函数,而不是 IEEE754-1985。微软似乎已经决定他们的市场不关心 C99 支持,所以他们没有费心提供它们。这是一种耻辱,但除非你们(开发人员)中有更多人抱怨,否则没有理由期望情况会发生变化。
全新的 754 标准 IEEE754-2008 需要这些功能(第 5.3.3 条,“logBFormat 操作”),但该版本的标准在未来几年内不会被广泛采用;即使它确实得到了广泛的采用,微软在 C99 中的十年里也认为不适合提供这些功能,那么他们为什么要仅仅因为它们在 IEEE754 标准中而费心提供它们呢?
编辑:请注意,scalb 和 logb 在 IEEE754-1985 附录“推荐函数和谓词”中定义,但所述附录明确“不是其中的一部分”说标准。
【讨论】:
mk 出于某种原因,您将我的答案标记为已接受,尽管我已明确表示我承认自己完全错误。我认为这个,最近的答案是最好的,事实上我现在要把它投票给 2。 mk,请至少撤消您对我的回答的接受。【参考方案3】:如果您知道自己使用的是 IEEE 系统(现在确实如此),则不需要这些函数:只需通过将双精度与 uint64_t 联合来直接检查位。假设您首先是为了提高效率而使用这些函数(否则您将使用更自然的操作,例如 log()
或 exp()
),因此请花一些精力将您的代码与浮点表示进行匹配可能是值得的。
【讨论】:
以上是关于如何在 MSVC++6 中声明 IEEE 数学函数,如“ilogbf”?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 MSVC 在 C++ 中定义外部 C 结构返回函数?
如何在Mingw Gcc中声明和链接到RoInitialize,RoUninitialize,RoGetActivationFactory和HSTRING函数