Pergunta

Poderia alguém por favor me ajude e me diga como incluir funções matemáticas IEEE em MSVC ++ 6? Tentei tanto e, mas eu ainda obter esses erros:

Erro C2065: 'ilogbf': não declarado identificador

Erro C2065: 'scalbnf': não declarado identificador

Foi útil?

Solução

Editar 3: Esperemos que esta será a minha última edição. Eu vim a perceber que eu não tratadas adequadamente esta questão em tudo. Vou deixar a minha resposta no lugar como um conto preventivo, e porque ele pode ter algum valor educativo. Mas eu entendo porque eu tenho zero de upvotes, e na verdade eu vou upvote resposta Andy Ross', porque eu acho que o seu é muito mais relevante (embora incompleta, pelo menos no momento da escrita). Parece-me o meu erro foi tomar as definições Man I encontrados para ilogbf () um pouco superficial. É uma função que recebe a parte inteira do log de um flutuador, o quão difícil pode ser isso para implementar? Acontece que a função é representação de ponto realmente sobre está IEEE flutuante, em particular o expoente (ao contrário da mantissa) parte dessa representação. I definitivamente deve ter percebido que antes de tentar responder à pergunta! Um ponto interessante para mim é como uma função pode eventualmente encontrar a parte expoente de um flutuador, como eu pensei que uma regra fundamental do C é que carros alegóricos são promovidos para duplas como parte de uma chamada de função. Mas isso é uma discussão toda separado é claro.

--- Fim de editar 3, começar de conto preventivo ---

Um pouco googling sugere estes são definidos em alguns sabores de Unix, mas talvez não se encontram em qualquer padrão POSIX ou ANSI e assim não fornecido com as bibliotecas MSVC. Se as funções não estão na biblioteca não serão declarados em math.h. Obviamente, se o compilador não pode ver declarações para estes símbolos externos não será feliz e você vai obter erros como os que você lista.

O trabalho óbvia em torno é criar suas próprias versões dessas funções, usando funções matemáticas que são fornecido. eg

#include <math.h>

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

Edit: Isto não está certo. Aparentemente, esta função deve usar o registro para a base 2, em vez de logaritmos naturais, de modo que o valor devolvido é realmente um expoente binário. Deve também ter o valor absoluto de seu parâmetro, de modo que ele vai trabalhar para números negativos também. Vou trabalhar até uma versão melhorada, se você me perguntar em um comentário, caso contrário, eu estou tentado a deixar isso como um exercício para o leitor: -)

A essência da minha resposta, ou seja, que ANSI C não requer esta função e que MSVC não inclui-lo, é aparentemente correta.

Edit 2: Ok, eu já enfraquecido e forneceu uma versão melhorada sem ser perguntado. Aqui está;

#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;
}

Outras dicas

Estas são funções C99, não IEEE754-1985. Microsoft parece ter decidido que o seu mercado não se preocupa com o apoio C99, para que eles não se preocuparam em fornecê-los. Isto é uma vergonha, mas a menos que mais de você (desenvolvedores) queixam-se, não há nenhuma razão para esperar que a situação vai mudar.

A marca 754 padrão novo, IEEE754-2008, requer estas funções (cláusula 5.3.3, "operações logBFormat"), mas essa versão do padrão não será amplamente adotado por vários anos; mesmo que faz chegar a adoção ampla, a Microsoft não viu o ajuste para fornecer estas funções para os anos dez estiveram no C99 então por que eles se preocupam em proporcionar-lhes apenas porque são no padrão IEEE754?

Editar: Note que scalb e logb são definidos no IEEE754-1985 Apêndice "Funções Recomendadas e predicados", mas disse apêndice é explicitamente "não uma parte" referida norma.

Se você sabe que está em um sistema IEEE (e nos dias de hoje, você faz), essas funções não são necessários: apenas inspecionar os bits diretamente pelo unioning o casal com um uint64_t. Provavelmente, você está usando essas funções no interesse da eficiência em primeiro lugar (caso contrário, você estaria usando operações mais naturais como log() ou exp()), de modo a gastar um pouco de esforço em combinar seu código para a representação de ponto flutuante é provavelmente vale a pena.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top