Jump to content
Sign in to follow this  
fredericopissarra

Pegando o expoente de um double...

Recommended Posts

Eis um problema simples que surgiu num forum que sigo... O sujeito queria um jeito de obter o campo do expoente de um double sem usar operadores aritméticos, lógicos, "address-of" e indireção, ou seja, os operadores +, -, *, /, %, &, |, ^ ou ~. Se isso fosse permitido, a solução seria tão simples como:

#include <stdint.h>

/* Estrutura de um 'double' */
struct double_s {
  uint64_t f:52;
  unsigned int e:11;
  unisgned int s:1;
};

int getext( double x )
{
  struct double_s *p = (struct double_s *)&x;

  return p->e - 1023;
};

Existe uma solução simples, usando uma função da libm, basta a chamada para frexp(). Mas, existe também uma solução matemática. Se você quer descobrir um expoente, use logaritmo:

png.latex.png.e84f54c901cccc8835077cbc61feaf0c.png

Ou seja:

int getext( double x ) { return floor(log2(fabs(x))); }

A razão do floor é que o expoente de uma estrutura em ponto flutuante marca o início da janela onde a fração se encontra. Para valores menores que 1 o logaritmo lhe dará valores negativos e precisamos do maior valor menor que x. Já que x pode ser negativo (e não estamos interessados no sinal), obter o seu valor absoluto impede de usarmos valores inválidos para o logaritmo.

Ambas as soluções com frexp e log2, são lentas (embora frexp seja a mais rápida delas).

De qualquer maneira, é um problema trivial... 😉

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...