Как объявить математические функции IEEE, такие как 'ilogbf' в MSVC++6?

Может ли кто-нибудь помочь и рассказать, как включить математические функции IEEE в MSVC++6? Я пробовал оба и, но я все еще получаю эти ошибки:

ошибка C2065: 'ilogbf': необъявленный идентификатор

ошибка C2065: 'scalbnf': необъявленный идентификатор

3 ответа

Решение

Редактировать 3: Надеюсь, это будет мое последнее редактирование. Я пришел к выводу, что я вообще должным образом не ответил на этот вопрос. Я собираюсь оставить свой ответ на месте как предостерегающий рассказ, и потому что он может иметь некоторую образовательную ценность. Но я понимаю, почему у меня нет нулевых голосов, и на самом деле я собираюсь поднять ответ Энди Росса, потому что я думаю, что он гораздо более актуален (хотя и неполен, по крайней мере, на момент написания). Мне кажется, моя ошибка заключалась в том, чтобы воспринимать определения Man, которые я нашел для ilogbf(), немного поверхностно. Это функция, которая принимает целую часть лога с плавающей точкой, насколько сложно это реализовать? Оказывается, что функция на самом деле является представлением 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, а не натуральные log, так что возвращаемое значение фактически является двоичным показателем. Он также должен принимать абсолютное значение своего параметра, чтобы он работал и для отрицательных чисел. Я поработаю над улучшенной версией, если вы спросите меня в комментарии, в противном случае мне хочется оставить это в качестве упражнения для читателя:-)

Суть моего ответа, то есть, что 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, поэтому зачем им их предоставлять только потому, что они соответствуют стандарту IEEE754?

edit: обратите внимание, что scalb и logb определены в Приложении IEEE754-1985 "Рекомендуемые функции и предикаты", но указанное приложение явно "не является частью" указанного стандарта.

Если вы знаете, что находитесь в системе IEEE (и в наши дни это делаете), эти функции не нужны: просто проверяйте биты напрямую, объединяя двойное число с uint64_t. Предположительно, вы в первую очередь используете эти функции в интересах эффективности (в противном случае вы бы использовали более естественные операции, такие как log() или же exp()), поэтому стоит потратить немного усилий на сопоставление вашего кода с представлением с плавающей запятой.

Другие вопросы по тегам