誰かが助けて、MSVC ++ 6にIEEE数学関数を含める方法を教えてもらえますか?との両方を試しましたが、それでも次のエラーが発生します。
エラーC2065:'ilogbf':宣言されていない識別子
エラーC2065:'scalbnf':宣言されていない識別子
誰かが助けて、MSVC ++ 6にIEEE数学関数を含める方法を教えてもらえますか?との両方を試しましたが、それでも次のエラーが発生します。
エラーC2065:'ilogbf':宣言されていない識別子
エラーC2065:'scalbnf':宣言されていない識別子
編集3:うまくいけば、これが私の最後の編集になります。私はこの質問にまったく適切に対処していないことに気づきました。私の答えは注意話として残しておきますが、それは教育的価値があるかもしれないからです。しかし、私が賛成票をゼロにしている理由を理解しています。実際、アンディ・ロスの回答ははるかに関連性が高いと思うので、賛成するつもりです(少なくとも執筆時点では不完全ですが)。私の間違いは、ilogbf()で見つけたManの定義を少し表面的にとることだったようです。これは、floatのログの整数部分を取得する関数ですが、実装するのはどれほど難しいでしょうか。関数の実際の内容は、IEEE浮動小数点表現、特にその表現の(仮数ではなく)指数部分であることがわかります。質問に答える前に、私は間違いなくそれを理解していたはずです!私にとって興味深い点は、関数がfloatの指数部分を見つける方法です。これは、Cの基本的なルールは、floatが関数呼び出しの一部としてdoubleにプロモートされることだと思ったからです。もちろん、それはまったく別の議論です。
---編集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の対数を使用する必要があるため、戻り値は実際には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;
}
これらはC99関数であり、IEEE754-1985ではありません。Microsoftは、彼らの市場はC99のサポートを気にしないと判断したようで、彼らはそれらを提供することを気にしませんでした。これは残念ですが、より多くの皆さん(開発者)が不満を言わない限り、状況が変わると期待する理由はありません。
まったく新しい754標準であるIEEE754-2008には、これらの関数(5.3.3節、「logBFormat操作」)が必要ですが、このバージョンの標準は、今後数年間は広く採用されません。広く採用されたとしても、MicrosoftはC99での10年間、これらの機能を提供するのに適しているとは考えていません。それでは、IEEE754標準に準拠しているという理由だけで、なぜわざわざこれらの機能を提供するのでしょうか。
編集: scalbとlogbはIEEE754-1985付録「推奨される関数と述語」で定義されていますが、この付録は明示的に上記の標準の「一部ではない」ことに注意してください。
IEEEシステムを使用していることがわかっている場合(そして最近ではそうなっています)、これらの関数は必要ありません。doubleをuint64_tと結合して、ビットを直接検査するだけです。おそらく、そもそも効率を上げるためにこれらの関数を使用しているので(そうでない場合は、log()
やなどのより自然な操作を使用することになりますexp()
)、コードを浮動小数点表現に一致させるために少し努力する価値があります。